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>
}