Reputation: 4011
There is something that I just can't figure out. Here is a basic React class-based component fetching some data from an endpoint:
import React from 'react';
import ReactDOM from 'react-dom';
class Example extends React.Component {
state = { info: {} };
componentDidMount() {
fetch('https://api.spacexdata.com/v2/info')
.then(response => response.json())
.then(data => {
const info = data;
this.setState(() => ({ info }));
});
}
render() {
return (
<div>
{/* the first h1 renders just fine */}
<h1>{this.state.info.name}</h1>
{/* the second throws an error: Cannot read property 'address' of undefined */}
<h1>{this.state.info.headquarters.address}</h1>
</div>
);
}
}
ReactDOM.render(<Example />, document.getElementById('root'));
Why is the second h1 tag giving me undefined??? I check the state in the react dev tools and the data is there... It is literally an object that has another object within it... If I copy paste that same object into the state it renders just fine...
Upvotes: 0
Views: 955
Reputation: 4159
The problem is the async nature of the promises, when you first render the component you start the promise but it will take some time to execute and resolve, so it didn't return the JSON yet.This means that info still being {}
and when you try to render your H1
<h1>{this.state.info.headquarters.address}</h1>
you will get the undefined error. Because this.state.info.headquarters
is undefined so you cannot access .address until the promise resolves(remember they are async)
just replace your initial state with this one(or something similar)
state = { info: {headquarters:{address:'loading...'} };
and you will be fine.
Upvotes: 1