Удалить прослушиватель событий при отключении
У меня был компонент более высокого порядка, который реагирует так:
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() на немонтированном компоненте. Это не-op. Проверьте код для неопределенного компонента.
Несмотря на то, что я удалил событие 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);
}
все, кажется, работает нормально, без каких-либо проблем.
Я чувствую, что они точно такие же, но второй отлично работает, в то время как первый из них вызывает ошибку в консоли, как упоминалось ранее!
Ответы
Ответ 1
.bind
всегда создает новую функцию, поэтому вам нужно сделать, как показано ниже, поэтому она добавляет и удаляет ту же функцию.
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);
}
Ответ 2
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) проблемы, с которыми он работал просто отлично.
Ответ 3
Рабочая версия для моего проекта с функцией стрелки и без привязки:
componentDidMount = () => {
window.addEventListener("wheel", this.onScroll, false);
};
componentWillUnmount() {
window.removeEventListener("wheel", this.onScroll, false);
}
onScroll = (e) => {
const item = this.refs.myElement;
if (e.deltaY > 0) item.scrollLeft += 200;
else item.scrollLeft -= 200;
};