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>
);
}
}
Related
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>
)
}
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
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!
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
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>
}
}