This is an example given in the react docs for fetching data with useEffect.
export default function Page() {
const [person, setPerson] = useState('Alice');
const [bio, setBio] = useState(null);
useEffect(() => {
let ignore = false;
setBio(null);
fetchBio(person).then(result => {
if (!ignore) {
setBio(result);
}
});
return () => {
ignore = true;
};
}, [person]);
When the state person changes, the component will re-render, with a new person name and then useEffect runs and set the state bio with the fetched data. Now the screen shows new person name and bio. But before useEffect runs, and as the component re-render with the new person name, screen will have new person name but old person’s bio for a short time. Is my understanding correct, if so is there any way to change this behavior
I am a new to react and if my question is dumb, please correct me.
2
Answers
Looks like you need a variable to control the status of getting data. I’m using
isLoading
for example. With it, you can decide what to show when waiting for the new bio, here is the div with loading… textIf you use two separate state that are updated independently, then yes, there can be occasional times when the two are not in "agreement", e.g. the current
bio
state may not be that of the currentperson
state.Using a
useEffect
hook like this might be considered a bit of an anti-pattern though. If the intent is for theperson
andbio
state to always be updated together then do thebio
fetch at the same time thatperson
will be updated, and enqueue the state updates to both when the UI has both new datas.Basic Example:
The above is the basic gist, but you should "fancy it up" with loading state/indicators, cancelling in-flight network requests (Using "isLoaded" flags in hooks became a bit of a React anti-pattern over the past couple years) if
Page
unmounts, etc in your actual code if that is something of a concern.