Reputation: 483
I'm trying to fetch the contents of a static JSON file and display it in react.js. I'm basing my code on the examples given Here The code compiles, but when I open the page in a browser, I get this error message:
TypeError: Cannot read property 'data' of null
Here's my component:
import React, { Component } from 'react';
class UserList extends Component {
async getData(){
const res = await fetch('/static/users.json');
const data = await res.json();
console.log("Got Data : " + data.length);
return this.setState(
{data:data}
);
}
componentDidMount()
{
this.getData();
}
render(){
return (
<ul>{this.state.data.map(item => <li>{item.title}</li>)} </ul>
)
}
}
export default UserList;
Upvotes: 0
Views: 177
Reputation: 893
Your initial state declaration is missign:
import React, { Component } from 'react';
class UserList extends Component {
state = {
data: []
};
// ...
}
export default UserList;
Upvotes: 0
Reputation: 655
Its because setState internals update asynchronously and may not be set by the time your code tries to read data.
You could do:
render(){
return (
<ul>{this.state.data && this.state.data.map(item => <li>{item.title}</li>)} </ul>
)
}
This will only try and map over your array if this.state.data
is not equal to null.
*** EDITED ****
You have also not constructed your state which is why the null check isn't working.
import React, { Component } from 'react';
class UserList extends Component {
constructor(props) {
super(props);
// Don't call this.setState() here!
this.state = {
data: null,
};
}
async getData(){
const res = await fetch('/static/users.json');
const data = await res.json();
console.log("Got Data : " + data.length);
this.setState({data});
}
componentDidMount()
{
this.getData();
}
render(){
return (
<ul>{this.state.data.map(item => <li>{item.title}</li>)} </ul>
)
}
}
export default UserList;
Upvotes: 0
Reputation: 116
getData
is an asynchronous function, as well as setState
. This creates a race condition between the time your component mounts, to the time it renders. Therefore you need to null check.
import React, { Component } from 'react';
class UserList extends Component {
async getData(){
const res = await fetch('/static/users.json');
const data = res.json();
console.log("Got Data : " + data.length);
return this.setState(
{data:data}
);
}
componentDidMount()
{
this.getData();
}
render(){
return (
<ul>{this.state && this.state.data && this.state.data.map(item => <li>{item.title}</li>)} </ul>
)
}
}
export default UserList;
Upvotes: 2