Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: Issue with using setState() with onScroll()

I have a React app with basically a fixed header -- <AppHeader> -- and the rest of the content -- <AppMain>. What I'm trying to do is add a drop shadow to the <AppHeader> when the window is scrolled. So I'm attaching an onScroll handler to a DIV around <AppMain>, and when I detect it's scrolled, I set a state variable scrolled, which gets passed to <AppHeader>, and that component can then deal with adding the appropriate drop shadow class. So my code more or less looks like:

class App extends Component {
  _handleScroll(e) {
    console.log('scrolling:', e.target.scrollTop);
    if (e.target.scrollTop > 0) {
      this.setState({ scrolled: true });
    } else {
      this.setState({ scrolled: false });
    }
  }

  constructor(props) {
    super(props);

    this._handleScroll = this._handleScroll.bind(this);
    this.state = {
      scrolled: false
    };
  }

  render() {
    return (
      <div className="App">
        <AppHeader scrolled={this.state.scrolled} />
        <div className="AppMainScroll" onScroll={this._handleScroll}>
          <AppMain />
        </div>
      </div>
    );
  }
}

The above code works well enough, and my <AppHeader> gets the appropriate prop value when the window is scrolled. However, I notice in my console that the _handleScroll() function keeps getting triggered when the div is scrolled, even if I'm not actively scrolling / interacting with the window. As I'm typing this, my console.log() in _handleScroll() has fired 2000 times, and that window isn't even in the foreground. If I scroll all the way back to the top, _handleScroll() no longer gets triggered.

Am I using onScroll and setState incorrectly here?

like image 403
accelerate Avatar asked Jun 01 '26 10:06

accelerate


1 Answers

I think this is what you're missing.

componentDidMount() {
  window.onscroll = () => this._handleScroll()
}

_handleScroll() {
  console.log('scrolling:', document.documentElement.scrollTop);
  if (document.documentElement.scrollTop > 0) {
    this.setState({ scrolled: true });
  } else {
    this.setState({ scrolled: false });
  }
}

https://codesandbox.io/s/nk6o110464

like image 127
byumark Avatar answered Jun 03 '26 07:06

byumark



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!