我有一个有状态组件,它具有这样的滚动事件侦听器
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));
}
但是它现在似乎不起作用。
答案 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;