user6815795
user6815795

Reputation:

Gatsby build getting window error while using onLoad

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

Answers (2)

Danilo Gacevic
Danilo Gacevic

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

Ferran Buireu
Ferran Buireu

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 or document. 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 if window 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 a componentDidMount lifecycle or into a useEffect 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

Related Questions