Reputation:
In my code im trying to get the div height by clientHeight by using onLoad. ComponentDdiMount doesnt give the clientHeight in this case as images load in the div.The code works fine for me.But when i try gatsby build i get the window error as im using onLoad. Is there any workaround for this?
export default class Mainpageanimation extends React.Component {
constructor(props) {
super(props);
this.topref = React.createRef();
}
load = () =>{
const centerheight = this.topref.current.clientHeight;
//animate div
}
render(){
return (
<div className="topdiv" ><img src={require("image.png") } ref={this.topref} onLoad=
{this.load}/></div>
);
}
}
Upvotes: 0
Views: 390
Reputation: 494
Try including onLoad property only when the code is running in the browser
export default class Mainpageanimation extends React.Component {
constructor(props) {
super(props);
this.topref = React.createRef();
}
load = () =>{
const centerheight = this.topref.current.clientHeight;
//animate div
}
render(){
return (
<div
className="topdiv" >
<img src={require("image.png") } ref={this.topref}
{...typeof window !== 'undefined' ? {onLoad: this.load} : {}}
/>
</div>
);
}
}
Upvotes: 1
Reputation: 29320
With gatsby build
, rather than gatsby develop
, some objects such as window
or document
are not defined at the point your code is requesting them. The usual errors are fixed by checking if the window is defined in a componentDidMount
lifecycle/useEffect
hook before triggering your function. From Gatsby's documentation:
Some of your code references “browser globals” like
window
ordocument
. If this is your problem you should see an error above like “window
is not defined”. To fix this, find the offending code and either a) check before calling the code ifwindow
is defined so the code doesn’t run while Gatsby is building (see code sample below) or b) if the code is in the render function of a React.js component, move that code into acomponentDidMount
lifecycle or into auseEffect
hook, which ensures the code doesn’t run unless it’s in the browser.
So, my first approach will be checking if the window
is defined:
load = () =>{
let centerHeight;
if (typeof window !== undefined){
centerHeight= this.topref.current.clientHeight;
//animate div
}
}
If this doesn't work, I would try to change your onLoad function and use it in a componentDidMount
directly:
export default class Mainpageanimation extends React.Component {
constructor(props) {
super(props);
this.topref = React.createRef();
}
componentDidMount(){
let centerHeight;
if (typeof window !== undefined){
centerHeight= this.topref.current.clientHeight;
//animate div
}
}
render(){
return (
<div className="topdiv" ><img src={require("image.png") } ref={this.topref} /></div>
);
}
}
Besides the answer, I think you should bind your reference. In a functional component arrow functions does it automatically but in a stateful component like yours, you must do it manually. In your constructor:
this.topref= this.topref.bind(this);
You can check for further information in Refs and the DOM by React documentation.
Upvotes: 0