I am trying to use a hook to determine the size of my window and am getting a build error when deploying to netlify
const toggle = () => setToggle(!isToggledOn);
var windowSize = 900;
if (window) {
windowSize = useWindowSize();
}
return (
WebpackError: ReferenceError: window is not defined
Here is my code
`import React, { useState, useEffect } from 'react';
import HeadLogo from './HeadLogo';
import useWindowSize from '@rehooks/window-size';
import TransitionLink from 'gatsby-plugin-transition-link';
import NavbarBrand from './styles/NavbarBrand';
import NavLinks from './styles/NavLinks';
import HamburgerMenu from './HamburgerMenu';
import isEntryExit from './isEntryExit';
import InnerDrop from './InnerDrop';
export default function Navbar() {
const [isToggledOn, setToggle] = useState(false);
const toggle = () => setToggle(!isToggledOn);
var windowSize = 900;
windowSize = useWindowSize();
return (
(isToggledOn && windowSize.innerWidth < 800) ||
windowSize.innerWidth > 800
}
/>
(isToggledOn && windowSize.innerWidth < 800) ||
windowSize.innerWidth > 800
? 'toggle-open'
: 'toggle-closed'
}
>
);
}
`
I have seen in other issues that set the function in a componentDidMount would solve the issue but that is not possible with hooks. Does anyone have any suggestions?
Thanks so much.
P.S this is my first post to GitHub :) So if I've left anything out of this question please let me know.
Did you already try typeof window !== 'undefined'
?
Try this
let windowsize = 900
if (typeof window !== 'undefined') {
windowsize = useWindowSize();
}
you probably want to define something closer to the actual object you want to use like:
let windowsize = { innerWidth: '900' }
can you please share your useWindowSize code also?
based on what you are trying to do, I think it should be something like this
function useWindowSize (defaultValue) {
const [windowSize, setWindowSize] = useState({ innerWidth: defaultValue })
useLayoutEffect(() => {
setWindowSize({ innerWidth: window.innerWidth })
}, [])
return windowSize
}
then in your component
const windowSize = useWindowSize(900)
Hey @PatrickLambert1101
The ReferenceError error is occurring because window
is not available during server side rendering (when gatsby build
is run)
To fix this, you need to run this code only on the client side. You can do this by calling the hook inside an effect. Depending on your use case, you can use useEffect or useLayoutEffect
Guys, just a note:
You can do this by calling the hook inside an effect
In a (function-based) component, hooks should be called only at the top level. Doc ref
@PatrickLambert1101 you'd need to adjust the hook itself. Defining default values in the outside scope and using them as default state should do the trick:
let defaultHeight
let defaultWidth
if (typeof window !== `undefined`) {
defaultHeight = window.innerHeight
defaultWidth = window.innerWidth
}
const useWindowSize = () => {
const [dimensions, setDimensions] = useState({
windowHeight: defaultHeight,
windowWidth: defaultWidth,
})
useEffect(() => {
const handler = () => setDimensions({
windowHeight: window.innerHeight,
windowWidth: window.innerWidth,
})
window.addEventListener(`resize`, handler)
return () => window.removeEventListener(`resize`, handler)
}, [])
return dimensions
}
Hiya!
This issue has gone quiet. Spooky quiet. 馃懟
We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
Thanks for being a part of the Gatsby community! 馃挭馃挏
Hey again!
It鈥檚 been 30 days since anything happened on this issue, so our friendly neighborhood robot (that鈥檚 me!) is going to close it.
Please keep in mind that I鈥檓 only a robot, so if I鈥檝e closed this issue in error, I鈥檓 HUMAN_EMOTION_SORRY
. Please feel free to reopen this issue or create a new one if you need anything else.
Thanks again for being part of the Gatsby community!
@PatrickLambert1101 you'd need to adjust the hook itself. Defining default values in the outside scope and using them as default state should do the trick:
let defaultHeight let defaultWidth if (typeof window !== `undefined`) { defaultHeight = window.innerHeight defaultWidth = window.innerWidth } const useWindowSize = () => { const [dimensions, setDimensions] = useState({ windowHeight: defaultHeight, windowWidth: defaultWidth, }) useEffect(() => { const handler = () => setDimensions({ windowHeight: window.innerHeight, windowWidth: window.innerWidth, }) window.addEventListener(`resize`, handler) return () => window.removeEventListener(`resize`, handler) }, []) return dimensions }
This solved my problem.
@Siregar
Where should I put this code ?
Most helpful comment
Did you already try
typeof window !== 'undefined'
?