0

I have a component, in which I've passed image url, but getting compiler error.

Service.js

import React from 'react';

const Service = (props) => {
  return (
    <div className="col-sm-6 col-md-6 col-lg-6 col-6">
      <div className="service">
        <img src={require(props.URL)} alt="pencil_logo" />
        <h4>{props.Title}</h4>
        <p>{props.Description}</p>
      </div>
    </div>
  );
};

export default Service;

About.js

const About = (props) => {
  console.log(props);

  let services = null;

  services = props.Services.map((x, index) => {
    return <Service {...x} key={index} />;
  });
  return(
    <div>{services}</div>
  );
};
export default About;

props.Services has the following values

{
  "Services": [
    {
      "Description": "testdata",
      "Title": "testdata",
      "URL": "../../../assets/images/site/pencil_tip.svg"
    },
    {
      "Description": "testdata2",
      "Title": "testdata2",
      "URL": "../../../assets/images/site/pencil_tip2.svg"
    },
    {
      "Description": "testdata3",
      "Title": "testdata3",
      "URL": "../../../assets/images/site/pencil_tip3.svg"
    }
  ]
}

When I run this app, i'm getting this erro

Uncaught Error: Cannot find module '../../../assets/images/site/pencil_tip.svg'

But When I use like this, it works perfectly fine.

import pencil from'../../../assets/images/site/pencil_tip.svg';
...
<img src={pencil} alt="pencil_logo" />

Why it's not finding the image dynamically and how to fix this and why it finds the image if hardcoded?

UPDATE #1:

I'm getting this warning in my terminal while building

Compiled with warning
../xx/xx/Service.js
Critical dependency: the request of a dependency is an expression
Ranjith Varatharajan
  • 1,596
  • 1
  • 33
  • 76

4 Answers4

0

If you want to use that way you cannot use .. in the url. You have to give full path of that image. When you use it in the import it convert that into a perfect url. But when you will pass it as a string that will not be converted into a perfect url. Perfect url means. Suppose I have an image in asset/img/img.jpg so when you import it using .. it convert the path into a full path. But as you passing a string it passes as the same. So it couldn't find it.

moshfiqrony
  • 4,303
  • 2
  • 20
  • 29
  • So I need to give a absolute path instead of a relative one? – Ranjith Varatharajan May 06 '20 at 14:29
  • Right. Suppose you import the image and it is showing? Then in the browser inspect see the image url. And refactor all the url in that same way. And that's way with the absolute url it will work fine. Another thing is if you hard code a relative url and pass it in the ```img``` it will not work. Because it is a string it is not using ```import``` keyword so it won't convert that relative url to a absolute url. – moshfiqrony May 06 '20 at 14:33
  • No man, I cannot give absolute path. It must be relative one. It seems `require` works static not dynamic – Ranjith Varatharajan May 06 '20 at 14:46
0
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
    const images = {
    "Services": [
     {
         "Description": "testdata",
          "Title": "testdata",
          "URL": './Assets/naruto.jpg'
     },
     {
          "Description": "testdata2",
          "Title": "testdata2",
          "URL": './Assets/naruto.jpg'
     },
     {
         "Description": "testdata3",
         "Title": "testdata3",
         "URL": './Assets/naruto.jpg'
     }
  ]
}
return (
   <div id="container">
       {images.Services.map( image => <img src={require(`${image.URL}`)} style={{width: '20%'}}/>)}
   </div>
);
  }

   export default App;

This was my code and it worked enter image description here

0

Anyways, i found out the answer. It seems the issue is with the require itself. We cannot pass the entire url as dynamic like this <img src={require(props.URL)} alt="pencil_logo" />.

require needs some part to be dynamic. so using

<img src={require('../../../assets/' + props.URL)} alt="pencil_logo"/> solved my problem

Ranjith Varatharajan
  • 1,596
  • 1
  • 33
  • 76
0

You cannot pass image urls like that because the compiler won't see that it needs to include them during the build. The preferred way would be to import the images into an array or object somewhere and then refer to them later via a key. Something like:

Images.js

import pencil from'../../../assets/images/site/pencil_tip.svg';
import pencil2 from'../../../assets/images/site/pencil_tip2.svg';
import pencil3 from'../../../assets/images/site/pencil_tip3.svg';

const images = {pencil, pencil2, pencil3};
export const getPencilTip(key) => {
  return images[key];
}

Then assuming your service returns

{
  "Services": [
    {
      "Description": "testdata",
      "Title": "testdata",
      "ImageKey": "pencil_tip"
    },
    {
      "Description": "testdata2",
      "Title": "testdata2",
      "ImageKey": "pencil_tip2"
    },
    {
      "Description": "testdata3",
      "Title": "testdata3",
      "ImageKey": "pencil_tip3"
    }
  ]
}

You can use it like this

import React from 'react';
import {getPencilTip} from './Images';

const Service = (props) => {
  return (
    <div className="col-sm-6 col-md-6 col-lg-6 col-6">
      <div className="service">
        <img src={getPencilTip(props.ImageKey)} alt="pencil_logo" />
        <h4>{props.Title}</h4>
        <p>{props.Description}</p>
      </div>
    </div>
  );
};
Long Nguyen
  • 426
  • 3
  • 8