I'm using the following hook (taken from Get viewport/window height in ReactJS). I've adapted the hook so it can be rendered on the server (by gating access to window
inside a conditional).
import { useState, useEffect } from 'react';
function getWindowDimensions() {
if (typeof window !== 'undefined') {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
return { width: -1, height: -1 }
}
export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowDimensions;
}
I've noticed something interesting / confusing:
- The hook does return the default values of
{width: -1, height: -1}
when it is rendered on the server - These values are seemingly observed by parent component. Example:
export default function FooComponent() {
const { width, height} = useWindowDimensions();
// this invariant fails
invariant(width > -1 && height > -1);
}
However, if I insert a console.log(width, height)
, below the invariant(...)
line, I never see -1, -1
in the browser console.
So it looks like the invariant
is only triggered on the server and console.log
is only run on the client. Can someone explain what's going on here? I.e, why does the component not observe default server side values?