通过其他功能设置组件的状态

时间:2019-03-05 06:12:51

标签: javascript reactjs components

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

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

但是它现在似乎不起作用。

1 个答案:

答案 0 :(得分:1)

只有相应的component可以处理其state,您可以在 AppDetailPageSF组件类似

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

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

更新状态的代码必须位于同一组件中,我们所能做的就是创建一个处理程序,并将该处理程序传递给我们想要从中进行更新。

  

解决方案是高阶组件

我建议像这样使用 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;