I'm currently building a test app using React Native. The Image module, thus far has been working fine.
For example, if I had an image named avatar
, the below code snippet works fine.
<Image source={require('image!avatar')} />
But but if I change it to a dynamic string, I get
<Image source={require('image!' + 'avatar')} />
I get the error:
Requiring unknown module "image!avatar". If you are sure the module is there, try restarting the packager.
Obviously this is a contrived example, but dynamic image names are important. Does React Native not support dynamic image names?
This question is related to
javascript
react-native
jsx
First, create a file with image required - React native images must be loaded this way.
assets/index.js
export const friendsandfoe = require('./friends-and-foe.png');
export const lifeanddeath = require('./life-and-death.png');
export const homeandgarden = require('./home-and-garden.png');
Now import all your assets
App.js
import * as All from '../../assets';
You can now use your image as an interpolated value where imageValue (coming in from backend) is the same as named local file ie: 'homeandgarden':
<Image style={styles.image} source={All[`${imageValue}`]}></Image>
Say if you have an application which has similar functionality as that of mine. Where your app is mostly offline and you want to render the Images one after the other. Then below is the approach that worked for me in React Native version 0.60.
const Images = { 'image1': require('./1.png'), 'image2': require('./2.png'), 'image3': require('./3.png') }
import React from 'react'; import { Image, Dimensions } from 'react-native'; import Images from './Index'; const ImageView = ({ index }) => { return ( <Image source={Images['image' + index]} /> ) } export default ImageView;
Now from the component wherever you want to render the Static Images dynamically, just use the ImageView component and pass the index.
< ImageView index={this.qno + 1} />
import React, { Component } from 'react';
import { Image } from 'react-native';
class Images extends Component {
constructor(props) {
super(props);
this.state = {
images: {
'./assets/RetailerLogo/1.jpg': require('../../../assets/RetailerLogo/1.jpg'),
'./assets/RetailerLogo/2.jpg': require('../../../assets/RetailerLogo/2.jpg'),
'./assets/RetailerLogo/3.jpg': require('../../../assets/RetailerLogo/3.jpg')
}
}
}
render() {
const { images } = this.state
return (
<View>
<Image
resizeMode="contain"
source={ images['assets/RetailerLogo/1.jpg'] }
style={styles.itemImg}
/>
</View>
)}
}
I know this is old but I'm going to add this here as I've found this question, whilst searching for a solution. The docs allow for a uri: 'Network Image'
https://facebook.github.io/react-native/docs/images#network-images
For me I got images working dynamically with this
<Image source={{uri: image}} />
If you're looking for a way to create a list by looping through a JSON array of your images and descriptions for example, this will work for you.
const Profiles=[_x000D_
{_x000D_
"id" : "1",_x000D_
"name" : "Peter Parker",_x000D_
"src" : require('../images/user1.png'),_x000D_
"age":"70",_x000D_
},_x000D_
{_x000D_
"id" : "2",_x000D_
"name" : "Barack Obama",_x000D_
"src" : require('../images/user2.png'),_x000D_
"age":"19",_x000D_
},_x000D_
{_x000D_
"id" : "3",_x000D_
"name" : "Hilary Clinton",_x000D_
"src" : require('../images/user3.png'),_x000D_
"age":"50",_x000D_
}_x000D_
]_x000D_
export default Profiles;
_x000D_
import Profiles from './ProfilesDB.js';_x000D_
_x000D_
<FlatList_x000D_
data={Profiles}_x000D_
keyExtractor={(item, index) => item.id}_x000D_
renderItem={({item}) => (_x000D_
<View>_x000D_
<Image source={item.src} />_x000D_
<Text>{item.name}</Text>_x000D_
</View>_x000D_
)}_x000D_
/>
_x000D_
Good luck!
As the React Native Documentation says, all your images sources needs to be loaded before compiling your bundle
So another way you can use dynamic images it's using a switch statement. Let's say you want to display a different avatar for a different character, you can do something like this:
class App extends Component {
state = { avatar: "" }
get avatarImage() {
switch (this.state.avatar) {
case "spiderman":
return require('./spiderman.png');
case "batman":
return require('./batman.png');
case "hulk":
return require('./hulk.png');
default:
return require('./no-image.png');
}
}
render() {
return <Image source={this.avatarImage} />
}
}
Check the snack: https://snack.expo.io/@abranhe/dynamic-images
Also, remember if your image it's online you don't have any problems, you can do:
let superhero = "spiderman";
<Image source={{ uri: `https://some-website.online/${superhero}.png` }} />
This worked for me :
I made a custom image component which takes in a boolean to check if the image is from web or is being passed from a local folder.
// In index.ios.js after importing the component
<CustomImage fromWeb={false} imageName={require('./images/logo.png')}/>
// In CustomImage.js which is my image component
<Image style={styles.image} source={this.props.imageName} />
If you see the code, instead of using one of these:
// NOTE: Neither of these will work
source={require('../images/'+imageName)}
var imageName = require('../images/'+imageName)
I'm just sending the entire require('./images/logo.png')
as a prop. It works!
Important Part here: We cannot concat the image name inside the require like [require('item'+vairable+'.png')]
Step 1: We create a ImageCollection.js file with the following collection of image properties
ImageCollection.js
================================
export default images={
"1": require("./item1.png"),
"2": require("./item2.png"),
"3": require("./item3.png"),
"4": require("./item4.png"),
"5": require("./item5.png")
}
Step 2: Import image in your app and manipulate as necessary
class ListRepoApp extends Component {
renderItem = ({item }) => (
<View style={styles.item}>
<Text>Item number :{item}</Text>
<Image source={Images[item]}/>
</View>
);
render () {
const data = ["1","2","3","4","5"]
return (
<FlatList data={data} renderItem={this.renderItem}/>
)
}
}
export default ListRepoApp;
If you want a detailed explanation you could follow the link below Visit https://www.thelearninguy.com/react-native-require-image-using-dynamic-names
Courtesy : https://www.thelearninguy.com
You should use an object for that.
For example, let's say that I've made an AJAX request to an API and it returns an image link that I'll save to state as imageLink
:
source={{uri: this.state.imageLink}}
<StyledInput text="NAME" imgUri={require('../assets/userIcon.png')} ></StyledInput>
<Image
source={this.props.imgUri}
style={{
height: 30,
width: 30,
resizeMode: 'contain',
}}
/>
in my case i tried so much but finally it work StyledInput component name image inside the StyledInput if you still not understand let me know
you can use
<Image source={{uri: 'imagename'}} style={{width: 40, height: 40}} />
to show image.
from:
https://facebook.github.io/react-native/docs/images.html#images-from-hybrid-app-s-resources
To dynamic image using require
this.state={
//defualt image
newimage: require('../../../src/assets/group/kids_room3.png'),
randomImages=[
{
image:require('../../../src/assets/group/kids_room1.png')
},
{
image:require('../../../src/assets/group/kids_room2.png')
}
,
{
image:require('../../../src/assets/group/kids_room3.png')
}
]
}
when press the button-(i select image random number betwenn 0-2))
let setImage=>(){
//set new dynamic image
this.setState({newimage:this.state.randomImages[Math.floor(Math.random() * 3)];
})
}
view
<Image
style={{ width: 30, height: 30 ,zIndex: 500 }}
source={this.state.newimage}
/>
RELEVANT IF YOU HAVE KNOWN IMAGES (URLS):
The way I hacked my way through this problem:
I created a file with an object that stored the image and the name of the image:
const images = {
dog: {
imgName: 'Dog',
uri: require('path/to/local/image')
},
cat: {
imgName: 'Cat on a Boat',
uri: require('path/to/local/image')
}
}
export { images };
Then I imported the object into the component where I want to use it and just do my conditional rendering like so:
import { images } from 'relative/path';
if (cond === 'cat') {
let imgSource = images.cat.uri;
}
<Image source={imgSource} />
I know it is not the most efficient way but it is definitely a workaround.
Hope it helps!
Source: Stackoverflow.com