I have a custom hook useWindowSize
that listens to changes of the window size. Once the window size is below a certain threshold, some text should disappear in the Menu
. This is implemented in another custom hook useSmallWindowWidth
that takes the returned value of useWindowSize
and checks whether it is smaller than the threshold.
However, even though only the nested state changes, my component rerenders constantly when the window size changes. Rerendering the menu takes about 50ms on average which adds up if I want to make other components responsive as well.
So how could I keep the component from rerendering? I tried React.memo
by passing return prev.smallWindow === next.smallWindow;
inside a function, but it didnt work.
My attempt so far:
//this hook is taken from: https://stackoverflow.com/questions/19014250/rerender-view-on-browser-resize-with-react
function useWindowSize() {
const [size, setSize] = useState([0, 0]);
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}
window.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
return size;
}
function useSmallWindowWidth() {
const [width] = useWindowSize();
const smallWindowBreakpoint = 1024;
return width < smallWindowBreakpoint;
}
function Menu() {
const smallWindow = useSmallWindowWidth();
return (
<div>
<MenuItem>
<InformationIcon/>
{smallWindow && <span>Information</span>}
</MenuItem>
<MenuItem>
<MenuIcon/>
{smallWindow && <span>Menu</span>}
</MenuItem>
</div>
);
}
You can try wrapping all your JSX inside a useMemo
Put in the array in the second argument of the useMemo what variable should make your jsx rerender. If an empty array is set (like in the exemple), the jsx never rerenders.