React Native: Require() with Dynamic String

React Native - Image Require Module using Dynamic Names

This is covered in the documentation under the section "Static Resources":

The only allowed way to refer to an image in the bundle is to literally write require('image!name-of-the-asset') in the source.

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

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

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

However you also need to remember to add your images to an xcassets bundle in your app in Xcode, though it seems from your comment you've done that already.

http://facebook.github.io/react-native/docs/image.html#adding-static-resources-to-your-app-using-images-xcassets

React native require Image dynamically on state update with many possible options

I've figured it out using an "images.js" helper file.

In "App.js" I'm updating the image path depending on a "target" state value.

import {getImage} from './images';

// Image is updated based on this value
const [target,setTarget] = useState("default");

// Default image path
const [imagePath,setImagePath] = useState({path: getImage('default')})

useEffect(() => {
setImagePath({
path: getImage(target);
});
},[target])

return(
<View>
<Image source={imagePath.path} />
</View>
)

And here's "images.js" which is in the same path as a folder called "pictures":

export function getImage(input) {
switch (input) {
case "value_1": return require('./pictures/Picture1.png');
case "value_2": return require('./pictures/Picture2.png');
case "value_3": return require('./pictures/Picture3.png');
...
case "value_149": return require('./pictures/Picture149.png');
case "value_150": return require('./pictures/Picture150.png');
case "default": return require('./pictures/placeholder.png');
}
}

Creating the above function can be tedious so I created a python script that outputs the switch result programmatically to an output file and I simply copied pasted the output into this file.

React Native Dynamic Images

Depending on the number of images that you are expecting you could try placing an images.js file in your assets/images folder and require them as such:

// assets/images/images.js
const images = {
rohit: require("./rohit.png"),
bhavya: require("./bhayva.png")
}
export default images;

Then in your MainComponent, if you were to trim off the assets:/ part of the string in the uri then you could use:

import images from "../assets/images"

{initialArr.map((prop, key) => {
return (
<View style={styles.container}>
<Image source={images[prop.uri]} style={styles.image}></Image>
<Text key={key}>{prop.uri}</Text>
</View>
);
})}

If you are dealing with a large number of images, then your images.js file will become difficult to maintain, in that case you could try using a plugin like https://github.com/dushaobindoudou/babel-plugin-require-all and then write a small script which will create an dictionary of your images like:

// prepareImages.js
const fs = require("fs");
const files = fs.readdirSync("./assets/images").filter(x => x.includes("png"));
const ex = "{\n" +
files.map(x => `"${x.split(".png")[0]}": require("./${x}"),`).join("\n") + "}";
const res = "export default " + ex;
fs.writeFileSync("./assets/images/index.js", res);

React Native - Dynamic Image Source

I don't think this is possible because react native needs to know what to bundle ahead of time (AFAIK). However, you can require all the files in your array:

var SECTIONS = [
{
title: 'One',
file: require('../images/one.jpeg'),
},
{
title: 'Two',
file: require('../images/two.jpeg'),
},
{
title: 'Three',
file: require('../images/three.jpeg'),
},
{
title: 'Four',
file: require('../images/four.jpeg'),
},
];

{SECTIONS.map((section, i) => (
<CategoryCard
key={i}
source={section.file}
title={section.title}
/>
))}


Related Topics



Leave a reply



Submit