I'm trying to render several images from an array, passed onto an "Image" component as a property. However, for whatever reason, the local images I would like to render are not showing up. If I load an image hosted at a web address, that image will show up, indicating that there is nothing wrong with the "imageSource" property being passed onto the Image component. I have tried playing with the source format like so:
let source = 'require(./img/' + props.imageSource + ")";
or trying:
<img src={{uri: source}} role="presentation" style={style.image} />
...but nothing I do makes any difference.
The component is as seen below. I am totally stuck, so help would be much appreciated!
import React from 'react';
let Image = function statelessFunctionComponentClass(props) {
let source = './img/' + props.imageSource;
const style = {
image : {
width: '400pt',
height: '400pt'
}
}
return (
<img src={source} role="presentation" style={style.image} />
)
}
export default Image
You can include the folder of images by creating a new context with require.context(). From there, you can dynamically access the image you want from that folder, and set it as a src.
Going off of a structure like this:
APP
├──webpack.config.js
├──src
├──containers
├──YourContainer.js
├──components
├──YourComponent.js
├──public
├──bundle.js
├──images
├──dog.png
├──cat.png
In YourContainer.js, you want to create a new context to require that images directory
const images = require.context('../../public/images', true);
From there, you can reference an image specifically:
const dog = images('./dog.png');
or dynamically:
let animal = images(`./${someVariable}.png`);
For a more full example, here's how you can do it while iterating over an object, using the keys to pull your image, and passing that as a style prop to a child component:
let YourContainer = ({ dispatch }) => {
const data = projectData["projectData"];
// Require context image folder
const images = require.context('../../public/images', true);
return (
<div className="container-fluid">
<Row>
{
// Iterate over data object
Object.keys(data).map((keyname, keyindex)=> {
let code = data[keyname]["code"];
let title = data[keyname]["title"];
// Dynamically reference image
// Set as inline style
// Pass as prop to child
let imgsrc = images(`./${code}.png`);
let styler = {
backgroundImage: `url(${imgsrc})`
}
return <YourComponent
key={keyindex}
title={title}
style={styler}
/>
})
}
</Row>
</div>
)
}
The Problem
The problem you were having was mixing in the local "require" style using relative paths on the filesystem and the URL paths that operate similarly, but slightly differently.
For example:
require('./some-resource.x')
tells the build system to look for a file in the local directory relative to the current file. The important point is that it is the build system that uses this.
When you're in a React component, or any running javascript in the browser, there is no concept of the local disk, only the page/window context within which it is running.
It is not really valid to do the following:
require('/img/some_image.jpg')
nor
<img src="./img/some_image.jpg" />
Because the first refers to the root of the filesystem, which is unlikely to be what you want, and the second refers to a concept which browsers don't really support (disclaimer: they might work with it, I haven't tested it).
I think it is likely that your img
directory is not relative to where the bundle is created.
What should you do?
If you follow the usual structure of having a public
folder, then maybe images
(or img
in your case), then the webserver will serve the public directory according to it's config, which could be http://server/public
or http://server/static
or even just directly under the root address (http://server/
).
In the context of the DOM, which is the page/window context mentioned above, it only makes sense to refer to an image in either the current location, so http://server/path/to/page/img/image.jpg
, or the root location. Either way, you should do something like this:
import React from 'react';
const Image = function statelessFunctionComponentClass(props) {
let source = props.imageIsRelative ?
'img/' + props.imageSource :
'/img/' + props.imageSource;
const style = {
image : {
width: '400pt',
height: '400pt'
}
}
return (
<img src={source} role="presentation" style={style.image} />
)
}
export default Image
Notice that the difference is simply the /
at the front, which indicates whether the path is relative to the current page or the root of the webserver.
来源:https://stackoverflow.com/questions/41947474/dynamically-loading-local-images-with-reactjs