This is a document which tries to collect common Pitfalls that developers fall into when learning React for the first time.
This is usually caused by misunderstanding the component lifecycle. Components in React render synchronously, which means that the first time a component renders it will often have no data, or empty data.
Example:
import { useState, useEffect } from 'react';
import { getPosts } from 'api';
function App() {
const [posts, setPosts] = useState();
useEffect(() => {
getPosts.then(posts => setPosts(posts))
}, [])
return (
<div className="posts">
{posts.map(post => <Post key={post.id} post={post}/>)}
</div>
)
}
In this example the first time this component loads, because we passed nothing into useState
the state will be undefined,
Then in the JSX, we call posts.map
which is trying to call the map function on an undefined value.
Since useEffect
is asynchronous, it does not call the getPosts
method on initial render. Instead React will call useEffet
after render.
Once we have gotten the list of posts, we then call setPosts
which updates the state of the component and triggers a re-render of the component.
One solution to this problem is to make sure we have some initial state we can call .map
on, so by making the initial state an empty array, we accomlish that goal:
const [posts, setPosts] = useState([]);
Conditional rendering if often the best solution to this problem. Basically guard against empty data in the function by checking to see if you have the data.
if (!posts) {
return <p>There are no posts</p>
}