React JS 滚动优化

3

我在React组件中使用onscroll事件,代码如下:

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>
    }
};

这段代码可以正常工作,但有时会冻结,我猜测是因为handleScroll函数触发太频繁了。那么我的问题是如何优化这段代码?


我认为在生命周期方法中不需要添加“addEventListener”。您可以直接绑定div,例如onScroll={this.handleScroll}。 - kag
2个回答

2
尝试对handleScroll方法进行以下修改。
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})
    }
}

编辑:代码行数更少。

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});
    }
}

这样,只有当UI需要更改时,setState方法才会被触发。

耶!这好多了!非常感谢! - Mad Max

0
我们可以减少一些检查。
handleScroll = () => {
if(!this.contentRef) return;

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

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

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接