The misunderstanding about useEffect has deps
the easy thing but we still get a mistake about it
The Problem
Almost we understand: the func return in useEffect will be run when component unmount, true but not enough.
The Explanation
The func return in useEffect run when component unmount only if the deps is a empty array. If the deps is not a empty array, the useEffect will be run like componentDidUpdate and the the func return when run before the next render. You can see the below codesanbox
Initially, The text count change will be printed (mounting), then you change count, the text run before the next time render will be printed before count change (re-rending).
The steps in background:
- Apply effect
- Clean up prev effect after apply new effect
- Loop it
The example from react docs, more clearly.
function FriendStatus(props) {
// ...
useEffect(() => {
// ...
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
There is no special code for handling updates because useEffect handles them by default. It cleans up the previous effects before applying the next effects. To illustrate this, here is a sequence of subscribe and unsubscribe calls that this component could produce over time:
// Mount with { friend: { id: 100 } } props
ChatAPI.subscribeToFriendStatus(100, handleStatusChange); // Run first effect
// Update with { friend: { id: 200 } } props
ChatAPI.unsubscribeFromFriendStatus(100, handleStatusChange); // Clean up previous effect
ChatAPI.subscribeToFriendStatus(200, handleStatusChange); // Run next effect
// Update with { friend: { id: 300 } } props
ChatAPI.unsubscribeFromFriendStatus(200, handleStatusChange); // Clean up previous effect
ChatAPI.subscribeToFriendStatus(300, handleStatusChange); // Run next effect
// Unmount
ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // Clean up last effect
source: useEffect hook
Comments