Dynamically Loading Local Images with ReactJS

為{幸葍}努か 提交于 2019-12-03 09:02:12

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 imgin 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!