skip to Main Content

I am trying to paste a path to a picture within the img tag with the require() method.

This is the component. Props are passed from the parent correctly because console.log(img) return the correct path.

import data from '../asset/data/blog-post.json'

function BlogPostFeed() {
    const post = data.map(item => {
        return <BlogPost
            key={item.id}
            img={item.img}
        />
    })
    return (
        <>
            {post}
        </>
    )
}

function BlogPost(props) {
    const { img } = props;
    return (
        <>
            <img src={require(img)} alt="photo" />
        </>
    )
}

This is what the json file looks like.

[ 
 {
        "id": 1,
        "img": "../photo/photo.jpeg"  
 }
]

I am sure all the folder path are correct.

I tried to paste the path <img src={require"../photo/photo.jpeg"} alt="sth"/> and is working. However, neither <img src={require(img)} or <img src={require(${img})} alt="sth"/> would work.

I have also tried altering the json file to "img": require("../photo/photo.jpeg") but then an error for json file comes up.

An error Cannot find module '../photo/photo.jpeg' pops up.

2

Answers


  1. Chosen as BEST ANSWER

    With reference to the following post, I have worked out a simpler solution by changing the .json file to .js file. Then, as suggested by the post, I convert the data to const data = [ { id: 1, img: require("../photo/photo.jpeg") } ] export default data;

    Then in the component, I just used <img src={img} alt="sth"/>

    How to use template literals in require? (require(`${somePath}`))


  2. The error is related to how the webpack, which underlies React, works with the require() function. require() is not a standard JavaScript function, but a feature provided by Node.js and webpack. require() performs a synchronous read of the module during the build process, which means that webpack needs to understand the dependencies between modules at build time (before the app runs), not at runtime.

    So, when you use require("../photo/photo.jpeg") directly, webpack knows to include this file in the build bundle because the path is static, not dynamic. However, when you try to use require(img), webpack doesn’t know what file you’re referring to until the code runs, which is too late.

    In this case, I would suggest two possible solutions:

    1. Using dynamic imports:

    This is a feature provided by modern JavaScript, and webpack supports it too. Here is how you could use it in your component:

    import React, { useState, useEffect } from 'react';
    
    function BlogPost(props) {
        const { img } = props;
        const [imgSrc, setImgSrc] = useState();
    
        useEffect(() => {
            import(`../${img}`)
            .then((image) => setImgSrc(image.default))
            .catch((err) => console.error(err));
        }, [img]);
    
        return (
            <>
                {imgSrc && <img src={imgSrc} alt="photo" />}
            </>
        );
    }
    

    Note that you need to provide a relative path from the root directory of your project in your JSON file for this to work.

    1. Using public folder to serve the images:
      If you’re using create-react-app, you can put your images in the public folder. Then, you can refer to these images by their path relative to the public folder:
    function BlogPost(props) {
        const { img } = props;
        return (
            <>
                <img src={process.env.PUBLIC_URL + '/photo/photo.jpeg'} alt="photo" />
            </>
        );
    }
    

    Note that in your JSON file, you just need to provide the path from the public directory.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search