Reputation: 3
In componentDidMount (), I get the data and pass it to the state.
componentDidMount() {
const url = fetch('http://localhost:8000/posts/')
.then(response => response.json())
.then(response => {
this.setState({ data: response });
})
}
Next I try to get the data of this.state.data[0].id
In this case, I get the error
TypeError: cannot read property 'id' of undefined
But if I try to get data through this.state.data[0]
, then an object comes in, where there is a property id
Upvotes: 0
Views: 754
Reputation: 17598
You are fetching your data from a remote source and this fetch operation is asynchronous. In the initial render of your app you don't have this data yet.componentDidMount
triggers the fetch and your data lands in your app. So, you should use a conditional rendering as recommended in the comments. Here is a simple example:
class App extends React.Component {
state = {
posts: []
};
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/posts")
.then(response => response.json())
.then(posts => {
this.setState({ posts });
});
}
render() {
const { posts } = this.state;
return <div>{!!posts.length && posts[0].title}</div>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
And with a little enhancement. Because I'm pretty sure that you won't use a single data item in your app. As a future reference, you can use this simple logic. A better approach would be refactoring this code and writing a separate Post
component.
class App extends React.Component {
state = {
posts: []
};
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/posts")
.then(response => response.json())
.then(posts => {
this.setState({ posts });
});
}
render() {
const { posts } = this.state;
if (!posts.length) return <p>Loading...</p>;
return (
<div>
{posts.map(post => (
<div key={post.id}>
<p>{post.title}</p>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 2