0

Under my "img" folder I have 5 folders: ("America", "Europe", "Asia", "Africa", "Australia"). Each of these folders contains several city images (Europe folder will hold London.jpg, Paris.jpg, Rome.jpg etc... for example)

Now, my reducer returns me 2 props. One represent the continent, and the other a city that belongs to the continent held in the previous prop.

What I want to achieve is to dinamically load the city image.

something like this:

var icon = (this.props.myContinent && this.props.myCity) ? 
      require('./img/'+{this.props.myContinent}+'/'+{this.props.myCity}+'.png');

<Image source={icon} />

I read this and this and they gave me an idea. But I'm still unable to solve this.

3 Answers 3

2

You can create icon component with object of paths to images and then in container just put city name to kind prop.

const paths = {
  'paris': require('./img/europe/paris.png'),
  'london': require('./img/europe/london.png'),
}


export default function Icon({ kind }) {
  return (
    <Image
      source={paths[kind]}
    />
  );
}

Then in container something like

<Icon kind={this.props.city} />
Sign up to request clarification or add additional context in comments.

1 Comment

Re-usability is key in React and this will work well. Just need to pass the continent in as well.
1

Your code is not working because the image name in require has to be known statically. According to the docs:

// GOOD
<Image source={require('./my-icon.png')} />

// BAD
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />

// GOOD
var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
<Image source={icon} />

While this is a bit inconvenient, it is fairly easy to implement. In your case, I would to the following:

const images = {
    america: {
        caracas: require('images/america/caracas.png'),
        newyork: require('images/america/newyork.png')
    },
    europe:{
        london: require('images/america/london.png'),
        paris: require('images/america/paris.png')
        rome: require('images/america/rome.png')
    },
    asia:{
        // And so on...
    }
}

Then, your icon initialization should look like this:

var icon = (this.props.myContinent && this.props.myCity) ? images[this.props.myContinent][this.props.myCity] : null;

And in render you can do something like this. The '&&' mechanism is simply there to check if icon is null:

{icon && <Image source={icon} />}

2 Comments

That's a bit inconvenient, I have hundreds of cities. But it works
I agree with you, if you have a lot of images it is a bit of a pain. Maybe you can automate the creation of the images object using a node script that recursively searches for image files and outputs the object.
0

Issue is you are not using ternary condition properly. You are using ? without :. use some image when condition fails.

Write it like this:

var icon = (this.props.myContinent && this.props.myCity) ? 
    require(`./img/${this.props.myContinent}/${this.props.myCity}.png`) 
  : require('./img/defaultImage.png');

<Image source={icon}/>

3 Comments

I get this error: Requiring unknown module "./img/Europe/London.jpg". If you are sure the module is there, try restarting the packager or running "npm install".
i think, its not able to find out the image, check your folder structure.
I tried with: require('./img/Europe/London.jpg') and it shows the image then I tried with require('./img/'+this.props.myContinent+'/London.jpg') and it gives: Requiring unknown module "./img/Europe/London.jpg". If you are sure the module is there....

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.