DevNotes
@devnotes ·
React Part 7: Load data with useEffect
So far, components have only drawn things. Sometimes a component also needs to reach outside React: load data from a server, start a timer, or change the tab's title. That's what useEffect is for.
The basic idea
useEffect takes a function, and React runs it after the component appears on the screen. The function you return from it is the cleanup. React runs it before running the effect again, and when the component goes away, so the timer doesn't keep ticking for a clock nobody can see.
The dependency array
The second argument tells React when to run the effect again:
[]: once, after the component first appears.[userId]: after it first appears, and again wheneveruserIdchanges.- No array at all: after every single draw. You'll rarely want that.
List every prop and state value the effect uses. Leave one out and the effect keeps using an old value.
Loading data
How the pieces fit:
- Two pieces of state cover the three things a person can see: loading, an error, or the user.
- The effect depends on
userId, so it loads again whenever that prop changes. - After the first load, a new
userIdkeeps the old user on screen until the new one arrives, so "Loading..." shows only the first time. - The
ignoreflag handles a race. IfuserIdchanges while the first request is still on its way, the cleanup marks that request as stale, so a slow, old answer can't overwrite the newer one.
The function you give useEffect can't be async itself, because React expects it to return nothing or a cleanup function. So the effect defines load inside and calls it. (A catch without a name in brackets is fine when you don't need the error itself.)
It runs twice while you're developing
In development, when a component first appears, React runs each effect, cleans it up, and runs it again. That's deliberate. The Vite starter wraps your app in <StrictMode>, which does this to catch effects that forget to clean up. It doesn't happen on your live site. If the double run breaks something, your cleanup is missing.
When you don't need an effect
Effects are for talking to things outside React. Don't use them to work out values from props or state, like filtering a list or joining a first and last name. Calculate those directly while drawing, as in React Part 6. An effect there only adds an extra draw and a place for bugs to hide.
In bigger apps, most teams load data with a library like TanStack Query, or a framework like Next.js, which handle caching and loading states for you. Knowing how useEffect works makes both of those much easier to follow.
Try it
Make a page with a number input for a user id, from 1 to 10, and a UserCard below it. Pass the number in with Number(e.target.value), and show the user's name, email and city with a loading and an error message.
Next: React Part 8: Build a to-do app
Join WIK to like and reply to DevNotes and see more like this.