I am learning React Native. Following the guide, Getting Started of Facebook (
https://facebook.github.io/react-native/docs/props ). When I tried to make a new component containing an image sometimes works and sometimes not. I have read online that this is due to how they are load, React Native doesn't support dynamic loading of images.
class CuteImage extends Component {
render() {
return (
<View>
<Image source={{uri: 'https://cdn1.medicalnewstoday.com/content/images/articles/322/322868/golden-retriever-puppy.jpg'}} />
</View>
);
}
}
export default class ExampleComponent extends Component {
render() {
return (
<View style={{alignItems: 'center', justifyContent: 'center', flex: "1", flexDirection: "column"}}>
<CuteImage />
</View>
);
}
}
I expected this to work fine because in the Image Component tutorial they did something similar and it had worked ( https://facebook.github.io/react-native/docs/image ) but it throws me the following error:
Failed to construct 'Image': Please use the 'new' operator
Why is this happening? How dynamic and static loading relates to this?
I think you forgot to add dimensions for your image.
The docs say here that you have to provide them when using network and data images.
I attached a screenshot of the result, it works now.
<View>
<Image style={{width: 380, height: 340} } source={{uri: 'https://cdn1.medicalnewstoday.com/content/images/articles/322/322868/golden-retriever-puppy.jpg'}} />
</View>
Cheers.
Related
I am trying to retrieve image data for an <Image> component in React Native.
The problem is the API I'm getting data from sometimes doesn't have an image source. So I have this code to check if the source.uri is not empty and if it is the image will be replaced by one I have saved in the project. The problem is that when the source.uri is null my image doesn't appear and instead there's a black space.
import noImage from '../assets/noImage.jpg'
render()
{
return (
<Image
style={{ width: SCREEN_WIDTH / 3, height: 13 }}
borderRadius="10"
resizeMode="stretch"
source={item.restaurant.thumb ? { uri: item.restaurant.thumb } : { noImage }} />
);
}
You could probably try this.
render(){
return(
<Image style={{width:SCREEN_WIDTH/3, height:130}} borderRadius="10" resizeMode="stretch" source={item.restaurant.thumb ? {uri: item.restaurant.thumb} : require('../assets/noImage.jpg')}}/>
)}
+require('../assets/noImage.jpg')
-import noImage from '../assets/noImage.jpg'
-{noImage}
I guess your "noImage" is not a web link, so you need to use require
source={item.restaurant.thumb ? {uri: item.restaurant.thumb} : require('path/noImage.png'})}
I am new to react native development. I have login screen in that login screen i have logo image, for that i have kept image in resource folder and given that path in code. But getting unable to resolve module.
Why this error coming don't know.
The following is the code
import React, {Component} from 'react';
import {StyleSheet, Text, View,TextInput,TouchableOpacity,StatusBar,Image} from 'react-native';
export default class App extends Component {
static navigationOptions = {
title: "Welcome",
header: null,
}
render() {
// const { navigate } = this.props.navigation
return (
<View style={styles.container}>
<StatusBar
barStyle="light-content"
backgroundColor="#003366"
/>
<Text style={styles.welcome}>SEDC</Text>
<View style={styles.user}>
<Image source={require('./resource/ic_userid.png')}/>
<TextInput placeholder="Acct No/User Id" style={styles.textInput} underlineColorAndroid={'rgb(0,0,0)'}></TextInput>
</View>
<TextInput placeholder="Password" style={styles.textInput} underlineColorAndroid={'rgb(0,0,0)'}></TextInput>
<TouchableOpacity style={styles.btn} onPress={this.login}><Text style={{color: 'white'}}>Log In</Text></TouchableOpacity>
</View>
);
}
login=()=>{
// alert("testing......");
this.props.navigation.navigate('Profile');
}
}
And the following is the project view in visual studio.
The code is in Login.js and images are in resource folder. But why the bellow error coming. This is the image code
<Image source={require('./resource/ic_userid.png')}/>
But this is the very small question and duplicate, But I don't know why error is coming. So please guide me how to do this.
Thanks In Advance
The Image you are hitting is in the wrong directory. You are looking in the /components for a resource directory.
<Image source={require('../../resource/ic_userid.png')}/>
Remember ./ means current directory.
Your App directory is as so:
App.js
- app
- components
- Login
Just try this <Image source={require('../../resource/ic_userid.png')}/> instead of using this <Image source={require('./resource/ic_userid.png')}/>
I have component in application with SectionList which parses its content from local json file. List item has image and text and when require image using varibale it causes error: calls to require expect exactly 1 string literal argument, but this was found: item.logo.
My json file
{
"algorithms":[
{"title":"Sorting algorithms","logo":"../logos/sorting.png"},
{"title":"Graph theory","logo":"../logos/graph.png"},
{"title":"Strings","logo":"../logos/strings.png"},
{"title":"Greedy technique","logo":"../logos/greedy.png"},
{"title":"Dynamic programming","logo":"../logos/dp.png"}
],
"datastructures":[
{"title":"Trees","logo":"../logos/tree.png"},
{"title":"Lists","logo":"../logos/list.png"},
{"title":"Tries","logo":"../logos/trie.png"},
{"title":"Stack and Queue","logo":"../logos/stack.png"},
{"title":"Hash Tables","logo":"../logos/hashtable.png"}
]
}
And renderItem function
renderItem = ({item}) => {
return(
<TouchableWithoutFeedback onPress={()=>this.props.navigation.navigate('List')}>
<View style={styles.itemHolder}>
<Image resizeMode="center" style={styles.itemLogo} source={require(item.logo)}/>
<View style = {styles.itemNameHolder}>
<Text style = {styles.itemName}>{item.title}</Text>
</View>
<View style={styles.itemPointer}>
<Image style={{width:50,height:50,}} source={require('../icons/right-arrow.png')}/>
</View>
<Divider/>
</View>
</TouchableWithoutFeedback>
);
}
Edited
Function require in js does not work dynamically. It's argument must be string.
Edit:
I think you need to use a workaround of map
first, you need to find a way to make the logo format to be like this
const data = [
{"title":"Sorting algorithms","logo": require('../logos/sorting.png')},
{"title":"Graph theory","logo": require('../logos/graph.png')},
]
Then when you want to use it just do like this
render() {
return (
<View>
{data.map((item) => {
<View>
<Image
style={styles.image}
source={item.logo}
/>
</View>
})}
</View>
);
}
let me know if it is work or not
I already extracted data from firebase and displaying them. Now i need to display images also. In firebase database i have the same structure as the image below
And I have a folder under my project that contains all images with the exact same name like for an example "Carl.png"
I extracted the photo content in and combined with the rest of the path : "Myproject/img/"+photo+".png" and it's displayed correctly in the screen. But when i try to affect it to image i get errors. And here is the code i tried
<Image style={{width: 50, height: 50}} source={{uri : (this.props.item.imageName)}}> </Image>
and i get this and if i try to put in <Image style={{width: 50, height: 50}} source={{ uri: <Text> this.props.item.imageName </Text> }}> </Image> i get this
and if i put this code source={require(this.props.item.imageName)}
here is what i get: unknown named module
Try loading it using require because you are loading it from a local storage, so your source attribute becomes:
source={ require('./img/'+photo+'.png') }
try with
<Image style={{width: 50, height: 50}} source={{uri : (this.props.item.imageName)}} />
You've got space between opening & closing tag.
actually, React native does not support the dynamic images even if they are stored locally and you just need to make their name dynamically variable. So, the only solution that i was obliged to use was to use a massive switch case and here the code i used:
switch (item.name) {
case 'carl':
return (
<Image source{require('pathUnderProject/carl.png')}/>
);
...
default:
return (
<View >
<Text>{'Null'}</Text>
</View>
);
I know it's not the best solution, but at least i'm sure it's working fine and it won't break in the production environment
I am working on a react native app where I am trying to make some images act like a button so that when you press on them they print a statement in the console.
The images are displayed like this:
The code I have is:
class ImageList extends Component {
componentWillMount(){
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.dataSource = ds.cloneWithRows(this.props.images);
}
imageTouched(){
console.log('pressed');
}
renderRow(rowData){
const {uri} = rowData;
return(
<View style={{padding: 1, alignSelf: 'flex-start'}}>
<TouchableHighlight onPress={this.imageTouched}>
<Image style={styles.imageSize} source={{uri: uri}} />
</TouchableHighlight>
</View>
)
}
render() {
return (
<View>
<ListView
contentContainerStyle={styles.list}
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
</View>
);
}
}
var styles = StyleSheet.create({
imageSize: {
//newWidth is the width of the device divided by 4.
//This is so that four images will display in each row.
width: newWidth,
height: newWidth,
padding: 2
},
list: {
flexDirection: 'row',
flexWrap: 'wrap'
}
});
When I run it there are no errors but when I touch the images nothing happens. I have checked the console but nothing is printed.
How do I get each image to act as a button?
Like others have mentioned, the problem is that this is not bound in the renderRow()-method. I think the easiest way to fix this is to change renderRow() to be an arrow-function:
renderRow = (rowData) => {
const {uri} = rowData;
return (
<View style={{padding: 1, alignSelf: 'flex-start'}}>
<TouchableHighlight onPress={this.imageTouched}>
<Image style={styles.imageSize} source={{uri: uri}} />
</TouchableHighlight>
</View>
);
}
Arrow function always have this set to their containing scope when invoked, so now this.imageTouched will resolve.
Notice that you don't have to do anything with your imageTouched()-function or invocation, since it's not referencing this.
PS. This syntax depends on Public Class Fields, which is a Stage 2 proposal of the language standard at the time of writing (likely to be included, already in use in internal React-code). This feature is possible to use with a babel-plugin that is enabled by default in React Native projects.
PS2. Note that declaring the method with an arrow function instead of using an arrow function in the invocation will create one instance of the method per component instance, instead of one instance per render. This should really be fine performance-wise.
React components defined as ES6 classes do not autobind methods' this context to the component instance. In this particular case, the renderRow callback is not bound and the context refers to the global application context instead, so the reference to this.imageTouched is undefined.
A common pattern you see a lot is to bind the callbacks in your render method:
<ListView
renderRow={this.renderRow.bind(this)}
/>
This, however, has the effect of creating a new instance of the function on every render, which causes unnecessary work for the garbage collector.
Another alternative is to use (lexically scoped) arrow functions and call the methods explicitly:
<ListView
renderRow={(data) => this.renderRow(data);
/>
But this has the same unwanted effect of unnecessarily creating functions on every render.
A slightly more verbose, but more "correct" way is to bind the callbacks in the class constructor:
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
}
Try this
<TouchableHighlight onPress={() => this.imageTouched()}>
Make sure to bind renderRow
renderRow={this.renderRow.bind(this)}