I know there are multiple similar questions here already, but I can't see which asynchronous fix I need to make in order to make this work.
I have a Next.js website where I want to render a video but only when we're on desktop. I don't want the video at all to be there on mobile to save the user from downloading it in the first place, and in order to do that I wrote my own React hook to keep track of the window size.
I can use the isDesktop in my code and it all works, and since I am still in development phase I added the window resize listener so I can easily test things by just resizing my window rather than reloading the page each time.
Everything works as expected, except for this dreaded message:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
which is driving me nuts. I have this code:
import { useState, useEffect } from 'react';
export function useWindowSize() {
const isBrowser = typeof window !== 'undefined';
const [isDesktop, setIsDesktop] = useState<boolean>(false);
function update() {
setIsDesktop(window.innerWidth >= 768);
}
useEffect(() => {
if (isBrowser) {
update();
window.addEventListener('resize', update, false);
return () => {
window.removeEventListener('resize', update, false);
};
}
}, [isBrowser]);
return { isDesktop };
}
and as soon as I comment out the update call in the useEffect, the message disappears. But then I no longer get the initial state (meaning, it will not render the video on my desktop page until i start resizing the window, and that's not what should happen).
The problem is that you are conditionally calling the useEffect cleanup function, it should always be static. Try putting the isBrowser condition inside the cleanup function
useEffect(() => {
if (isBrowser) {
update();
window.addEventListener('resize', update, false);
}
return () => {
isBrowser && window.removeEventListener('resize', update, false);
};
}, [isBrowser]);