Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React JS scroll optimization

I use onscroll event in my React component like this:

import React, { Component } from 'react';
import throttle from 'lodash/throttle';

class Example extends Component {
    state = {
        navigationFixed: false,
    }

    componentDidMount() {
        window.addEventListener('scroll', this.throttledHandleScroll);
    }

    componentWillUnmount() {
        window.removeEventListener('scroll', this.throttledHandleScroll);
    }

    handleScroll = () => {
        this.contentRef && this.setState({
           navigationFixed: window.scrollY >= this.contentRef.offsetTop - 32,
    });

    throttledHandleScroll = throttle(this.handleScroll, 80); // Using lodash throttle here

    render() {
       //Some variables and components here
       ...
       <section
            className={cx(s.content, {
                [s.navigationFixed]: this.state.navigationFixed,
            })}
            id="content"
            ref={(ref) => {this.contentRef = ref}}
            >
            ...
            //Another components here
       </section>
    }
};

And this is works fine, but it get freeze sometimes, I guess it is because of handleScroll function, which fires too often. So my question is how can I optimise this code?

like image 655
Mad Max Avatar asked Feb 07 '26 12:02

Mad Max


1 Answers

Try this modification to the handleScroll method.

handleScroll = () => {
    if(!this.contentRef) return;

    const navShouldBeFixed = window.scrollY >= this.contentRef.offsetTop - 32

    if(this.state.navigationFixed && !navShouldBeFixed) {
        this.setState({navigationFixed: false});
    } else if (!this.state.navigationFixed && navShouldBeFixed) {
        this.setState({navShouldBeFixed: true})
    }
}

EDIT: Less lines of code.

handleScroll = () => {
    if(!this.contentRef) return;

    const navShouldBeFixed = window.scrollY >= this.contentRef.offsetTop - 32

    if(this.state.navigationFixed && !navShouldBeFixed || 
       !this.state.navigationFixed && navShouldBeFixed) {
        this.setState({navigationFixed: navShouldBeFixed});
    }
}

This way the setState method is only fired when the UI requires a change.

like image 116
Kyle Richardson Avatar answered Feb 09 '26 02:02

Kyle Richardson



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!