G. Hamaide G. Hamaide - 4 months ago 295
iOS Question

React native Image variable in name doesn't work

I'm trying to load an image that has a variable in it's source, something like this.

<View>
{_.map(this.state.ambiences, (id) => {
var image = require('../../assets/img/ambiances/icons/' + label + '.png'); // variable label equals "chic" here
var image2 = require('../../assets/img/ambiances/icons/chic.png');
return <Image style={styles.pastilleOverlay} source={image} />;
})}
</View>


I get the following error (thrown when trying to set variable image) : Requiring unknown module "../../assets/img/ambiances/icons/chic.png"

If I comment the
var image = ...
line, it works fine with
source={image2}
in the Image tag.

I checked, both strings in the are exactly the same. Any ideas ?

Answer

Workaround

Maybe this Issue could help you.

We intentionally don't support dynamically generated image names because it makes it very hard to manage assets over time, just like how you wouldn't want to do var MyComponent = require('./' + libName + typeOfComponent); or something like that. Dynamic image name generation like this also won't work with the new dynamic asset managing system we're rolling out which let's you add and update assets on the fly with just cmd+R (no more need to add to Xcode and recompile).

Bundled Images

The images you want to use, need to be bundled "via Xcode asset catalogs or Android drawable folder", as the documentation says. Also you have to specify the dimensions of the images manually.

Note that this approach provides no safety checks. It's up to you to guarantee that those images are available in the application.

<View>
    {_.map(this.state.ambiences, (id) => {
        return <Image style={styles.pastilleOverlay} source={{ uri: '../../assets/img/ambiances/icons/' + label + '.png' }} style={{width: 40, height: 40}} />;
    })}
</View>

Alternative

What do you think about using a switch- or if-statement?

<View>
    {_.map(this.state.ambiences, (id) => {
        switch (label) {
            case "chic":
                return <Image style={styles.pastilleOverlay} source={require('../../assets/img/ambiances/icons/chic.png')} />;
            case "otherimage":
                return <Image style={styles.pastilleOverlay} source={require('../../assets/img/ambiances/icons/otherimage.png')} />;
            default:
                return <Image style={styles.pastilleOverlay} source={require('../../assets/img/ambiances/icons/default.png')} />;
        }
    })}
</View>