Reputation: 4752
The issue is summarized well here; basically, if you have an async function in useEffect (which is where you'd expect such functions), you cause a re-render of your component for every state that is updated. I generally don't want to be bunching up things as in the authors solution/workaround, and to me this behavior doesn't make sense (you'd expect all your state updates to happen together).
Is this by design? If so, is there a better way to deal with this, such that I can perform all my updates without having to worry about ordering, etc? This feels like a bug, but maybe just a flaw in my understanding.
Code for reference:
export default function App (): JSX.Element {
const [user, setUser] = useState(null)
const [pending, setPending] = useState(false)
useEffect(() => {
setPending(true)
fetchUser().then((fetchedUser) => {
setPending(false)
setUser(fetchedUser) // This updated value won't initially be seen by other effects dependant on 'pending'
})
}, [])
// …
}
Upvotes: 2
Views: 625
Reputation: 4752
Ended up figuring this out; see this. You need to manually batch things currently, with ReactDOM.unstable_batchedUpdates(() => { ... })
. Despite the name, it is seemingly widely regarded as quite stable.
It is also corrected in the currently in-development Concurrent Mode for React.
Upvotes: 2