SaySomething
SaySomething

Reputation: 279

Why can I not call my function inside the render ()?

I am very new using React and I have the following problem; I have defined a function out of the return (), and I am calling it afterwards so it shows only when the page is loaded.

class Landing extends Component {
  render() {
    scrollbar = () => {
      const progress = document.getElementById("progressBar");
      const totalHeight = document.body.scrollHeight - window.innerHeight;
      window.onscroll = function () {
        const progressHeight = (window.pageYOffset / totalHeight) * 100;
        progress.style.height = progressHeight + "%";
      };
    };

    return (
      <div>
        <div id="progressBar"> {this.scrollbar()}</div>
        <div id="scrollPath"></div>
      </div>
    )
  }
}

The error that I get is:

"scrollbar is undefined" // Search for the keywords to learn more about each error.

Any help is much appreciated.

Thank you!

Upvotes: 1

Views: 61

Answers (3)

Zohaib
Zohaib

Reputation: 1037

1) Move your scrollbar function outside render.

2) remove () these braces while calling scrollbar inside render function.

  scrollbar = () => {
   const progress = document.getElementById("progressBar");
   const totalHeight = document.body.scrollHeight - window.innerHeight;
   window.onscroll = function () {
     const progressHeight = (window.pageYOffset / totalHeight) * 100;
     progress.style.height = progressHeight + "%";
   };
};

render() {
return (
  <div>
    <div id="progressBar"> {this.scrollbar}</div>
    <div id="scrollPath"></div>

Upvotes: -1

Brian Thompson
Brian Thompson

Reputation: 14355

First, you shouldn't be doing DOM manipulation like that when using react, so ideally you would rewrite the scrollbar function to be more inline with react.

The error you are getting is because this is referring to the class, meaning this.scrollbar is looking for a class property called scrollbar. You do not have a class property called scrollbar, but a function declared within the render method.

You have two options to solve this error.

Reference the function instead of a class property:

<div id="progressBar">{scrollbar()}</div>

Change the function to be a class property:

class Landing extends Component {
  scrollbar = () => {
    const progress = document.getElementById("progressBar");
    const totalHeight = document.body.scrollHeight - window.innerHeight;
    window.onscroll = function () {
      const progressHeight = (window.pageYOffset / totalHeight) * 100;
      progress.style.height = progressHeight + "%";
    };
  };

Once you do one of these, you still might see some unexpected behavior. By doing:

<div>{this.scrollbar()}</div>

You are rendering the result of the function call. The function has no return value though, so it will render undefined. Since it really doesn't need to be rendered, you can just call in inside the render function directly:

render() {
  this.scrollbar();

  return (
    <div>
      <div id="progressBar"></div>
      <div id="scrollPath"></div>
    </div>
  )
}

Upvotes: 0

Sohan
Sohan

Reputation: 588

You must define the method (scrollbar) above the render method.

class Landing extends Component {
    scrollbar = () => {
      const progress = document.getElementById("progressBar");
      const totalHeight = document.body.scrollHeight - window.innerHeight;
      window.onscroll = function () {
        const progressHeight = (window.pageYOffset / totalHeight) * 100;
        progress.style.height = progressHeight + "%";
      };
    };

  render() {
    return (
      <>
        <div id="progressBar">{this.scrollbar}</div>
        <div id="scrollPath"></div>
      </>
    )
  }
}

I hope this solve your issue. :)

Upvotes: 2

Related Questions