It contains a very serious breaking change: cleanup in useEffect is now being executed asynchronously. I might not be seeing something, but I think this means all patterns like the one below will now have hard to catch racing conditions.<p><pre><code> const [x, setX] = useState()
useEffect(() => {
let isMounted = true
someAsyncFunc(result => {
if (isMounted) {
setX(result) // should not be called on dismounted component
}
})
return () => { isMounted = false }
}, [])
return <MyComponent x={x} />
</code></pre>
In this example it's possible that component will be unmounted, then completion handler will run and try to modify state before cleanup function will be able to set the flag.<p>Imo choosing a different name for new useEffect would be better (like useAsyncEffect or introducing a parameter), because just changing its behavior won't even result in compilation errors or guaranteed run-time errors, only make old code unstable.<p>Is there a way to reliably detect if component is still mounted before updating it when doing async operations in effects?