【问题标题】:Set state of a component from another function从另一个函数设置组件的状态
【发布时间】:2019-03-05 06:12:51
【问题描述】:

我有一个有状态的组件,它有一个像这样的滚动事件监听器

import React, { Component } from 'react'
import { withRouter } from 'react-router'
import AppDetailPageUI from './AppDetailPageUI.js'


class AppDetailPageSF extends Component {
  constructor(props) {
    super(props);
    this.state = {
        scrolledDown:false,
    };

    this.handleScroll = this.handleScroll.bind(this);
  }

  render() {
    return (
      <AppDetailPageUI

        scrolledDown={this.state.scrolledDown}
      />
    );
  }


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

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

  handleScroll(event)  {

    if (window.scrollY === 0 && this.state.scrolledDown === true) {
      this.setState({scrolledDown: false});
    } 
    else if (window.scrollY !== 0 && this.state.scrolledDown !== true) {
      this.setState({scrolledDown: true});
    }
  }

}

export default withRouter(AppDetailPageSF)

这工作得很好。但是我想在许多有状态的组件中使用 handleScroll 方法,并且在每个组件中包含相同的方法并不是一个好习惯。

所以这就是我尝试的方法,我创建了另一个 HandleScrollUtil 函数,类似这样

const HandleScrollUtil = {
    handleScroll: function(component) {

    if (window.scrollY === 0 && component.state.scrolledDown === true) {
        component.setState({scrolledDown: false});
    } 
    else if (window.scrollY !== 0 && component.state.scrolledDown !== true) {
        component.setState({scrolledDown: true});
    }
  }
}

export default HandleScrollUtil

然后我尝试通过传递这个引用来调用这个方法

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

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

但它现在似乎不起作用。

【问题讨论】:

    标签: javascript reactjs components


    【解决方案1】:

    只有各自的component可以处理它的state,你可以在里面创建handler AppDetailPageSF 组件 类似于

    setScrollDownHandler = (event,scrollValue) =>{
     this.setState({scrolledDown: scrollValue});
    }
    

    然后您可以将此处理程序传递给任何具有prop 的组件,这是正确的方法。

    更新 State 的代码必须在同一个组件中,我们所能做的就是创建一个处理程序来处理它并将该 处理程序 传递到我们的位置想要更新它。

    解决方案是一个高阶组件

    我建议使用像这样的 HOC,它可以包装到您要使用的任何组件中。

    import React, { Component } from 'react';
    
    
    const withScrollHandler = (WrappedComponent) => {
        return class extends Component {
    
            componentDidMount() {
                  this.props.setScrollDownHandler();
            }
    
            componentWillUnmount() {
                  this.props.setScrollDownHandler();
            }
    
            render () {
                return (
                    <div>
                        <WrappedComponent {...this.props} />
                    </div>
                );
            }
        }
    }
    
    export default withScrollHandler;
    

    【讨论】:

    • 但是只有当组件之间存在父子关系时,我才能通过这个处理程序。我想在许多相互没有关系的组件中使用这个 handleScroll 方法,那么在每个组件中包含相同的方法是否是一种好习惯,因为它会导致重复代码?
    猜你喜欢
    • 2021-04-26
    • 2020-04-01
    • 2020-10-03
    • 2018-03-19
    • 2018-10-30
    • 2020-01-07
    • 1970-01-01
    • 2020-07-01
    • 2019-12-11
    相关资源
    最近更新 更多