Reputation: 11
What will be the output of the following component under react strict-mode?
import { useEffect } from "react";
export default function Learn() {
let x = 1;
console.log("outside ", x)
useEffect(() => {
console.log(x);
x = 2;
return () => console.log("destruct", x)
}, []);
console.log("end of fn ", x)
return (
<>
<p>value = {x}</p>
</>
);
}
I ran it on my machine and I got
outside 1
end of fn 1
outside 1
end of fn 1
1
destruct 2
2
But I can't understand why. As per my reasoning, it should've been
outside 1
end of fn 1
1
destruct 2
outside 1
end of fn 1
1
What I assumed (incorrectly) was that react strict mode will:
But that is not happening here. So what is happening here?
Upvotes: 1
Views: 53
Reputation: 125
React strict mode, in development, forces a double render. useEffect hook is not immediately called, it is scheduled to run after the component has been mounted. So during the first render the output will be
outside 1
end of fn 1
after this, react imedtiately rerenders the component so the logs will reapper. Second render outputs:
outside 1
end of fn 1
and then we get the useEffect logs
1
destruct 2
2
Now to the part where x is not reinitialised. use effect cleanup is called when the use effect hook is called again. In the cleanup the value of x is not changed so it will remain the same. So, useEffect is ran x is outputed (1) then x++ then react callse the use effect hook again, meaning it will call the cleanup function so 'desturct 2' and then print the x again (2) then x++. It is explained a little bit better here: Why is the cleanup function from `useEffect` called on every render?
Upvotes: 0