10

i'm passing the following as props.

const people=['Eliana','Stefania','Ahmed']

{
  people.map(function(name, index){
    return <Person item={index} name={name}/>;
  })
}

import Eliana from '../assets/imgs/people/eliana.png'
import Stefania from '../assets/imgs/people/stefania.png'
import Ahmed from '../assets/imgs/people/ahmed.png'

export default class Person extends React.Component {
  render() {
    return (
      <div>
        <img src={this.props.name} alt=''/>
     <li key={this.props.item}>{this.props.name}</li>
   </div>
    );
  }
}

what i'm doing here is using the above strings in the array to pass to a component and then generate images from that component by using the corresponding path, however when i pass the props, they display as strings, like Eliana would display as is in the img src?

how do i get corresponding paths? some kind of string conversion probably? i bet this is an easy one!

Gage Hendy Ya Boy
  • 1,456
  • 4
  • 17
  • 35
Fahad Bilal
  • 159
  • 2
  • 3
  • 14

2 Answers2

25

An easy fix for what you're asking about

<img src={require(this.props.name)} alt=''/>

But this is implying that you have the full path. What you currently have doesn't look like will work. In one way or another, each one has to end up with a path name, like this, when React interprets your code:

<img src={require('../assets/imgs/people/ahmed.png')} alt=''/>

A simple fix is to add the path as a string before your this.props.name. It's standardized so all you have to do is add the name in, like so:

<img src={require(`../assets/imgs/people/${this.props.name.toLowerCase()}.png`)}/>

Be sure to document this though. You definitely want to document this.

Andrew
  • 7,201
  • 5
  • 25
  • 34
  • 1
    × Error: Cannot find module "." webpackMissingModule C:/development/hybrid/src/components/person.js:23 yes its a rel path which works if i pass it directly to an img src, i'm not too sure how would i pass abs path here. from ./ and onwards, the root dir would be localhost right? – Fahad Bilal Sep 26 '17 at 03:33
  • The default behavior is relative path, not absolute path, if that was your question. Because your image paths are so well standardized, you can always just string interpolate. Let me update my answer. – Andrew Sep 26 '17 at 03:37
  • thanks that helped! voted up, might take a while to update :) – Fahad Bilal Sep 26 '17 at 03:47
  • another question if you have a min, why did this.props.name turned out as a name? i mean while this solution worked, i'd like to know how could we transform / parse that string to the value of imported file? – Fahad Bilal Sep 26 '17 at 03:53
  • You're not using those 3 imported images at all, if that's your question. I'd have to show you this in the form of another question if you want a full explanation, but the basic rundown is that you'd have to put those images in your parent and make an array of those images, as opposed to an array of string with just their names. – Andrew Sep 26 '17 at 03:57
  • yes, exactly, i get it that the images import arent being used at all now, and i could use the images from a parent where images are itsellf sent as props, like a key pair value or may be directly in an array. i think more of my question is how do you resolve a string to get the imported path, generically, for my better understanding, i'd open a question but lately they are telling me to add code and not ask such generic questions – Fahad Bilal Sep 26 '17 at 04:32
  • You're asking for a completely different design paradigm, which is totally ok. If I were in your position, I would make an entirely new object inside your image folder that contains all of the information you need as properties in your giant object. Then map over that object in your component. That way, the only file you would ever need to maintain is that object with all your images. If you do that, `Object.values` is your friend ;) – Andrew Sep 26 '17 at 04:40
  • thanks for your time! that did help :) – Fahad Bilal Sep 26 '17 at 04:44
  • the third option worked great for me – Claytronicon Dec 12 '18 at 00:43
3

You could just use concatenate the entire URL besides the name, then concatenate the name prop in it's place.

<img src={require('../assets/imgs/people/' + this.props.name + '.png')}
Gage Hendy Ya Boy
  • 1,456
  • 4
  • 17
  • 35
  • 2
    tried that, throws a webpack error, anything i'm trying to do with 'require' syntax throws a webpack error. i have set up a basic CRNA – Fahad Bilal Sep 26 '17 at 03:40
  • 1
    No, the only reason Gage's solution throws an error is because the image file names are all lower case, while your `this.props.name` string are upper case. – Andrew Sep 26 '17 at 03:42
  • @Andrew good catch! You can either lowercase it inside of the `people` array, or in the path string itself via `this.props.name.toLowerCase()` – Gage Hendy Ya Boy Sep 26 '17 at 03:43
  • 1
    @GageHendyYaBoy Yep. Saw the same possible issue in my solution as well. Ours are basically the same. I just used string interpolation and you used concatenation. – Andrew Sep 26 '17 at 03:46
  • 1
    yes, thanks! that helped! – Fahad Bilal Sep 26 '17 at 03:47
  • @GageHendyYaBoy another question if you have a min, why did this.props.name turned out as a name? i mean while this solution worked, i'd like to know how could we transform / parse that string to the value of imported file? – Fahad Bilal Sep 26 '17 at 03:53
  • @FahadBilal Hmm I guess I'm a little confused. Do you want to have this.props.name just be the image in the first place, rather than having to require it inline? – Gage Hendy Ya Boy Sep 26 '17 at 03:59
  • @GageHendyYaBoy while this has resolved successfully so i'd prolly let it be so. my question is, how do you resolve a string sent from props to match any import file? say, i've imported something and i want that triggered by props by this.props.xyz. let this.props.xyz have the value of "test" and test imports "abc.json" of an abs/rel path? – Fahad Bilal Sep 26 '17 at 04:34