1

I'm trying to render my images that I stored in my array by using the map() method. Unfortunately I'm getting error when I'm trying to render the image from array but without using mapping I could render the images but I need to write the codes line by line. Could anyone help me with the solution?

const CardList = ({robots}) => {
const cardComponent = robots.map((user, i) => {
    return <Card src={robots[i].src} id={robots[i].id} name={robots[i].name} email={robots[i].email}/>
})
return(
    <div>
    {cardComponent}
    </div>
);

My CardList Component

const Card = ({name, email, id, src}) => {

return(
   <div className='bg-light-green dib br3 pa3 ma2 grow bw db w-20'>
         <img className='personal ' alt='robots' src={require(`${src}`)}/>
        <div>
             <h1>{name}</h1>
            <p>{email}</p>
        </div>
    </div>
)

My Card Component i feel there is something wrong with src={require(${src})}

and this is the error that i'm getting from react DOM: error

Mohsen Alyafei
  • 4,765
  • 3
  • 30
  • 42
Gajhen
  • 11
  • 2

2 Answers2

1
yourArray.map((key, data) => {
  <ComponentToDisplay id={key} {...this.props} />
});
0

TLDR;

// All of these works

const fileNameExt = 'foo.jpg'
<img src={require('../images/' + fileNameExt)} />
<img src={require(`../images/${fileNameExt}`)} />

const fileName = 'foo'
<img src={require('../images/' + fileName + '.jpg')} />
<img src={require(`../images/${fileName}.jpg`)} />

// These does not work:

const myPathVariable1 = '../images/' + 'foo' + '.jpg'
<img src={require(myPathVariable1)} />

const myPathVariable2 = '../images/' + 'foo.jpg'
<img src={require(myPathVariable2)} />


Explanation: You can not pass a variable name as argument to require because webpack doesn't do program flow analysis to know the variable value.

Webpack can not know which module it should load as it is unable to extract (guess) any information (path) about the module you provided in a variable. Hence, it fails to load when the argument is a variable.

But, webpack can require with expression because it can extract some information about the path if you provide it correctly.

For example, let's say this is the directory structure:

example_directory
│
└───template
│   │   table.ejs
│   │   table-row.ejs
│   │
│   └───directory
│       │   another.ejs

Method 1: Using variable (would not work):

var myPath = './template/table-row.ejs'
require(myPath)  
// will not work as webpack can't extract anything path or file as myPath is just a variable

Method 2: Using expression (would work; involves some pattern webpack can understand):

var myPath = 'table'
require("./template/" + name + ".ejs")

Webpack can parse and generate below context from the expression in Method 2:

Directory: ./template            // webpack understand that there is this directory
Regular expression: /^.*\.ejs$/  // and this regex about the modules

So, it will load all the matching modules:

./template/table.ejs
./template/table-row.ejs
./template/directory/another.ejs  
// Note that it will load all matching even if we provide --> var myPath = 'table' shown above

So, whenever webpack see an "expression" (not the variable) in require. It loads all matching modules and generates a "Context Module" which has information of all such loaded modules as a result of above expression.

So, you need to provide an expression which webpack can understand and make context module by loading all matches.

This means dynamic requires are supported but will cause all matching modules to be included in the bundle. (And might increase your bundle size so you need to be careful when using the expression inside require)


Answer to your question:

To make this work:

<img className='personal' alt='robots' src={require(`${src}`)}/>

You need to do:

<img className='personal' alt='robots' src={require("../images/" + src)}/>
// loads everyting inside "../images/"

or, better:

<img className='personal' alt='robots' src={require("../images/" + src + ".png")}/>
// loads everything inside "../images/" ending with ".png"

You can use backticks i.e. template literals too:

`../images/${src}.png`
Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87