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?