我有更高级别的组件反应如下:
export default function (InnerComponent) {
class InfiniteScrolling extends React.Component {
constructor(props){
super(props);
}
componentDidMount() {
window.addEventListener('scroll', this.onScroll.bind(this), false);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.onScroll.bind(this), false);
}
onScroll() {
if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 50)) {
const { scrollFunc } = this.props;
scrollFunc();
}
}
render() {
return <InnerComponent {...this.props} />;
}
}
InfiniteScrolling.propTypes = {
scrollFunc: PropTypes.func.isRequired
};
return InfiniteScrolling;
}
卸载通过InfiniteScrolling
包装的组件后,仍然会抛出错误(当我滚动时):
警告:setState(...):只能更新已安装或已安装 零件。这通常意味着您在已卸载时调用了setState() 零件。这是一个无操作。请检查未定义的代码 成分
即使我确实删除了组件卸载上的scroll
事件。它没有用。
但是当我将代码更改为这样时:
constructor(props){
super(props);
this.onScroll = this.onScroll.bind(this);
}
componentDidMount() {
window.addEventListener('scroll', this.onScroll, false);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.onScroll, false);
}
一切似乎都运转良好,没有任何问题。
我觉得它们完全是一样的,但是第二个工作正常,而第一个工作正如前面提到的那样在控制台中抛出错误!
答案 0 :(得分:64)
您始终在创建新功能
constructor(props){
super(props);
this.onScroll = this.onScroll.bind(this); //bind function once
}
componentDidMount() {
window.addEventListener('scroll', this.onScroll, false);
}
componentWillUnmount() {
// you need to unbind the same listener that was binded.
window.removeEventListener('scroll', this.onScroll, false);
}
答案 1 :(得分:1)
componentDidMount() {
window.addEventListener('scroll', this.onScroll, false);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.onScroll, false);
}
// use arrow function instead
onScroll = () => {
if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 50)) {
const { scrollFunc } = this.props;
scrollFunc();
}
}
或者您可以使用Arrow函数来解决.bind(this)正常工作的问题。
答案 2 :(得分:0)
我的项目的带有箭头功能且无绑定的工作版本:
![Alt text](https://g.gravizo.com/source/custom_mark10?https%3A%2F%2Fraw.githubusercontent.com%2FTLmaK0%2Fgravizo%2Fmaster%2FREADME.md)
<details>
<summary></summary>
custom_mark10
digraph G {
size ="4,4";
main [shape=box];
main -> parse [weight=8];
parse -> execute;
main -> init [style=dotted];
main -> cleanup;
execute -> { make_string; printf};
init -> make_string;
edge [color=red];
main -> printf [style=bold,label="100 times"];
make_string [label="make a string"];
node [shape=box,style=filled,color=".7 .3 1.0"];
execute -> compare;
}
custom_mark10
</details>
答案 3 :(得分:0)
我知道这有点晚了,但是我只是遇到了这个问题,想与您分享我的解决方案,希望得到您的反馈。此解决方案包括react hooks
。希望你喜欢
// Declare a static listener.
const eventListeners = useRef();
// now let's create our scroll Handler
const scrollHandler = useCallback(() => {...},[]);
useEffect(() => {
// Here will be removing the static listener and then updated it for
// our new one since the first time will be empty it won't do anything.
window.removeEventListener('scroll', eventListeners.current, true);
// Then will set our current scroll handler to our static listener
eventListeners.current = scrollHandler;
// Here will be adding the static listener so we can keep the reference
// and remove it later on
window.addEventListener('scroll', eventListeners.current, true);
},[scrollHandler]);