React Native static images with variable path - image

Lets say i have map() loop inside my main component render() function.
<ScrollView>
{this.state.items.map((item, i) => {
return(
<MyItem key={i} item={item} />
)
})}
</ScrollView>
And the render() function of component:
<View>
<Text>{this.props.item.title}</Text>
<Image source={require('../relative_path_to_image/' + this.props.item.imageName + '.png')}
</View>
If i do it this way i get an error: 'Make sure the module exists...blah blah'
If i do it the following way i get the same error:
render(){
var imageSource= require('../relative_path_to_image/' + this.props.item.imageName + '.png');
return (
<View>
<Text>{this.props.item.title}</Text>
<Image source={imageSource}
</View>
)
}
And if i write it with hardcoded (see below) path everything works fine!
var imageSource= require('hardcoded_path_to_image.png');
So, i probably need a way to render images inside a loop with the require() function. I think it's a fair need to all apps, why is not working as expected?

you cannot require a dynamic path for an Image. The image path should be compeletey static. I would suggest you pass the static path as the props to the component.
For example:
class BlaBlaBla extends Component {
constructor () {
this.state = {
myPicsArray: [
require('path/to/some/image'),
require('path/to/someAnother/image'),
require('path/to/someAnotherAnother/image')
]
}
}
render() {
<ScrollView>
{this.state.items.map((item, i) => {
return(
<MyItem key={i} item={item} />
)
})}
</ScrollView>
}
}

Related

React Native using list of image in state with for loop

I'm beginner in react native. I want to use list of image and then push them to the child page with for loop
here is my code to explain what am I say.
state ={
a: ['./assest/image1.jpg','./assest/image2.jpg','./assest/image3.jpg'],
}
b = () => {
let d = [];
for (var i = 0; i<=this.state.a.lenght - 1; i++){
if (this.state.a[i] == ' ') { }
else {
d.push(<Child images={this.state.a[i]} />)
}
}
return d;
};
render() {
return <ScrollView style={styles.body}>
{this.b()}
</ScrollView>
}
}
And this is the code of child page which gives image url and set it to with props
constructor(props)
{
super(props);
}
render()
{
return <View style ={ styles.body}>
<Image style={styles.image}>{this.props.images}</Image>
</View>
}
}
What is the correct way to use list of image urls in state
And how to push them with for loop
state = {
a: ['./assest/image1.jpg','./assest/image2.jpg','./assest/image3.jpg'],
}
render() {
return (
<ScrollView style={styles.body}>
{
this.state.a.map((url,key) =>
<View style ={ styles.body}>
<Image
style={styles.image}
source={require(url)} // <--- changed
/>
</View>
)
}
</ScrollView>
)
}

React Native Image error Failed prop type: Invalid prop source supplied to ForwardRef(Image)

In my react-native app I have an component array with Image component inside, but i have this error
Warning: Failed prop type: Invalid prop source supplied to
ForwardRef(Image).
file CampaignPreview
render() {
return (
<TouchableOpacity>
<ImageBackground
source={ require(this.props.imageFilePath) }
>
</ImageBackground>
</TouchableOpacity>
);
}
File Home
render() {
let campaigns = [
{
id: 1,
name: "WildFit",
expire: 1868029014,
picFrame: "../assets/picture.jpg",
done: 0.75
}
];
let campaignViews = campaigns.map( c => {
return (
<CampaignPreview
imageFilePath={ c.picFrame }
name={ c.name }
completation={ c.done }
key={ c.id }
/>
);
});
let view = (
<View>
<ScrollView>
{ campaignViews }
</ScrollView>
</View>
);
return view;
}
but If i put string instead of this.props.imageFilePath it works
i seems that 'require(var)' is not possible in react native, i used require('location') forever, you can try save the string in variable.
require only accept literal s string
react native use variable for image file

Adding an image in React native

I got this code, and im supposed to add 3 different images to each row.
class SubRatingRowGroup extends Component {
onRatingPressed(elementName, rating) {
const cat = _.find(this.props.categories_tree.categories, {
name: elementName
});
cat.rating = rating;
this.props.setSubRatings(cat, rating);
}
handleClick = () => {
this.props.setCategories( this.props.categories_tree.categories);
this.props.openSubCategory(this.props.categories_tree, this.props.editable)
}
render() {
if (this.props.categories_tree && this.props.categories_tree.categories) {
let subRatingRows = [];
subRatingRows = this.props.categories_tree.categories.map((category, key) => (
<View style={{ flex: 1}} key={key}>
<View style={styles.ratingButtonRow}>
<View style={styles.buttonNameText} >
<Button title={category.name} onPress={this.handleClick} />
</View>
</View>
</View>
));
return (
<View >
{subRatingRows }
</View>);
}
return renderLoadingSpinner();
}
}
This will end with me rendering 3 rows with :
Enviromental
Social
Cultural
and i need 3 different backgrounds on these rows, i'm kinda new so i'm not sure what to do here. Would appreciate any help!

How to pass value to headerRight button

When use the react-navigation and add the headerRight button
...
class Screen extends React.Component {
static navigationOptions = {
headerRight: (
<TouchableOpacity>
<Icon .../>
</TouchableOpacity>
)
}
render() {
return (
<View />
)
}
}
Then I want to animate this button, but I encounter a problem when passing value
...
class Screen extends React.Component {
static navigationOptions = {
headerRight: (
<Animated.View style={animatedStyle}> <---- how to pass it
<TouchableOpacity>
<Icon .../>
</TouchableOpacity>
</Animated.View>
)
}
componentWillMount() {
this.animatedValue = new Animated.Value(0)
}
componentDidMount() {
Animated.timing(...}).start()
}
render() {
const interpolateRotation = ...
const animatedStyle = ... <---- the animatedStyle value
return (
<View />
)
}
}
I have tried the this.animatedStyle and animatedStyle for Animated.View, but it also can not effectiveness. It seems static navigationOptions is not inline within the class Screen
You can use this.props.navigation.setParams({ headerRightButtonStyle: this.animatedValue }) in constructor or componentWillMount to pass this value. Then read it like this:
static navigationOptions = ({ navigation }) => {
const params = navigation.state.params
return {
headerRight: (
<Animated.View style={params.headerRightButtonStyle}>
<TouchableOpacity>
<Icon .../>
</TouchableOpacity>
</Animated.View>
)
}
}
setParams will also trigger header rerender. You can use this method to pass header title/style/etc.
Related documentation: https://reactnavigation.org/docs/headers.html#using-params-in-the-title

Images in React native after switch case

I have a list of images that I want to display and I can't do that dynamically. So, I did a massive switch case to know which image to display each time: no in the render of the page, I made renderImage: a function that contains a switch case and then in the render of the component itself I use renderImage but I get every time Null (the default value that I set). Here is the code I used:
class CountryDetails extends Component {
constructor(props) {
super(props);
fl = this.props.flag
};
static propTypes = {
popRoute: React.PropTypes.func,
navigation: React.PropTypes.shape({
key: React.PropTypes.string,
}),
}
popRoute() {
this.props.popRoute(this.props.navigation.key);
}
render() {
console.log('image ' , fl)
return (
<Container>
<Header style={{ backgroundColor: '#C0C0C0' }} hasTabs>
<Body>
<Text style={{ color: '#FFF', fontSize:17, fontWeight:'bold'}}> {this.props.name} </Text>
</Body>
<Right>
<View> {this.renderImage()} </View>
</Right>
</Header>
</Container>
);
}
renderImage() {
console.log('image ' , fl)
switch (fl)
{
case 'image1':
return (
<Image source={require('path/image1.png')}/>
);
case 'image2':
return (
<Image
source={require('path/image2.png')}/> );
case 'image3':
return (
<Image
source={require('path/image3.png')}/> );
default:
return (
<View >
<Text>{'Null'}</Text>
</View>
);
}}}
I keep getting Null, the default value that I set, every time in the screen.
After trying <View> {this.renderImage()} <View/> I get this error:
RawText "" must be wrapped in an explicit <Text> component.
PS I have other components to return in my render method like title and footer.
I don't think that is the correct way to use Image. Try the following code:
// .. rest of the code
render() {
return (
<View>
{this.renderImage()}
</View>
)
}
renderImage() {
switch (img) {
case 'image1':
return (<Image source={require('path/image1.png')}/> );
// .. rest of the case
default:
return (
<Text>{'Null'}</Text>
);
}
}

Resources