Getting undefined is not an object in React native when rendering
I'm new to React
and React native
and am trying to retrieve data from an API
and then render it but I seem to be running into problems.
I can grab the data from the API
alright, but when I try and render
it I'm getting all sorts of errors.
Essentially all I'm trying to do is render the photos that are returned from the API. Should be simple right? Would appreciate anyone who can point me in the right track.
I'm getting errors like:
undefined is not an object (evaluating 'this.props.photos') in RenderPhotos_render
I may have jumped into React Native
too early...So excuse my lack of knowledge!
var AwesomeProject = React.createClass({
getInitialState: function() {
return {
isLoading: true,
photos: this.props.photos
};
},
componentWillMount: function(){
fetch("http://localhost:3000/api/photos/", {
method: "GET",
headers: {
"x-access-token":"xxxxx",
"x-key":"xxxx"
},
})
.then((response) => response.json())
.then((responseData) => {
AlertIOS.alert(
"GET Response",
"Search Query -> " + JSON.stringify(responseData)
)
this.setState({
isLoading: false
});
this.setState({
photos: JSON.stringify(responseData)
});
})
.done();
},
render: function() {
if(this.state.isLoading){
return <View><Text>Loading...</Text></View>
}
return (
<RenderPhotos photos={this.props.photos}/>
);
},
});
var RenderPhotos = React.createClass({
getInitialState: function() {
return {
photos: this.props.photos
};
},
render: function(){
var photos = Photos;
return (
<View>
<Text> {this.props.photos[0]} </Text>
</View>
)
}
});
Answer
You have two problems.
First, the prop you pass to RenderPhotos
is this.props.photos
, which is undefined in AwesomeProject
. Looking in the render()
function of RenderPhotos
, you try to access the element at index 0 of this.props.photos
, which is undefined. That's probably what's causing your error. I suspect you meant to set the photos prop equal to this.state.photos
in the render()
function of the AwesomeProject
component.
Second, inside componentWillMount()
of the AwesomeProject
component, you make two state changes after you get photos from the API:
this.setState({
isLoading: false
});
this.setState({
photos: JSON.stringify(responseData)
});
It's possible, but not guaranteed, that React might batch those two setState()
calls, so both state properties would be set at the same time and the render()
method would be called only once. However, if these setState()
functions are executed synchronously, the render()
function will be called while this.state.loading === false
and this.state.photos === undefined
. The RenderPhotos
component will mount and receive the prop photos={this.state.photos}
(after making the change I described above). Unfortunately, because this.state.photos
is undefined, you will encounter the same problem as above when you try to access this.props.photos[0]
inside the render()
function of RenderPhotos
. Here's my suggestion to fix your problem:
var AwesomeProject = React.createClass({
getInitialState: function() {
return {
isLoading: true,
photos: this.props.photos
};
},
componentWillMount: function(){
fetch("http://localhost:3000/api/photos/", {
method: "GET",
headers: {
"x-access-token":"xxxxx",
"x-key":"xxxx"
},
})
.then((response) => response.json())
.then((responseData) => {
AlertIOS.alert(
"GET Response",
"Search Query -> " + JSON.stringify(responseData)
)
// Set both state properties at the same time to avoid passing an undefined value as a prop to RenderPhotos
this.setState({
isLoading: false,
photos: JSON.stringify(responseData)
});
})
.done();
},
render: function() {
if(this.state.isLoading){
return <View><Text>Loading...</Text></View>
}
// RenderPhotos should receive this.state.photos as a prop, not this.props.photos
return (
<RenderPhotos photos={this.state.photos}/>
);
},
});
var RenderPhotos = React.createClass({
getInitialState: function() {
return {
photos: this.props.photos
};
},
render: function(){
var photos = Photos;
return (
<View>
<Text> {this.props.photos[0]} </Text>
</View>
)
}
});
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM