Answer specific to Next.js
Since you are using Next.js window
isn't defined until the code is run on the client side. As this question suggests, try setting an initial width on an useEffect
hook like this:
useEffect(() => setWindowSize(window.innerWidth), [])
Observe the empty brackets meaning the hook will be executed once on every render, which in this case means once it renders on the client's side.
Answer not specific to Next.js
In your hook, initialize it to window.innerWidth
instead of null
.
const [width, setWidth] = useState<number>(window.innerWidth)
Other observations
Also, I would suggest you set up a listener for resize on a separate useEffect
hook because the way it is right now the listener depends on windowSize
changing before being attached. Take for example this useIsVertical
hook:
const useIsVertical = () => {
const [isVertical, setIsVertical] = useState(false)
const onResize = () => {
const height = window.innerHeight
const width = window.innerWidth
height > width ? setIsVertical(true) : setIsVertical(false)
}
useLayoutEffect(() => {
onResize()
}, [])
useLayoutEffect(() => {
window.addEventListener('resize', onResize)
return () => window.removeEventListener('resize', onResize)
}, [])
return isVertical
}