※throttleやdebounceに限ったことではありません。
概要
たまたまvueを書いていて遭遇。
scrollやresizeイベントの負荷を減らす際、わりとよく使うthrottleやdebounce。
mountedでaddEventListenerして、
beforeDestroyでremoveEventListenerしているつもりが、
イベントが削除できていなかった。
失敗例
import { throttle, debounce } from 'lodash'
export default {
name: 'xxxxx',
mounted () {
window.addEventListener('scroll', throttle(this.handleScroll, 100))
window.addEventListener('resize', debounce(this.handleResize, 300))
},
beforeDestroy () {
window.removeEventListener('scroll', throttle(this.handleScroll, 100))
window.removeEventListener('resize', debounce(this.handleResize, 300))
},
methods: {
handleScroll: function () {
// scrollの処理
}
this.handleResize: function () {
// resizeの処理
}
}
}
成功例
window.removeEventListener()する際、
直接かかずに、ワンクッション置くような感じですね。
mounted () {
window.addEventListener('scroll', this.handleScroll)
window.addEventListener('resize', this.handleResize)
},
beforeDestroy () {
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('resize', this.handleResize)
},
methods: {
handleScroll: throttle(function () {
this.scroll()
}, 100)
handleResize: debounce(function () {
this.resize()
}, 300)
scroll: function () {
// scrollの処理
}
resize: function () {
// resizeの処理
}
}
reactの場合
methodをbind(this)したあと、
throttleなどの関数をconstructorで登録する。
import React from 'react';
import throttle from 'lodash.throttle';
class Scroll extends React.Component {
constructor(props) {
super(props);
this.scroll = this.scroll.bind(this);
this.trottledFunction = throttle(this.scroll, 100);
}
componentDidMount() {
window.addEventListener('scroll', this.trottledFunction, false);
}
scroll() {
//scrollの処理
}
参考
https://alligator.io/vuejs/lodash-throttle-debounce/
https://stackoverflow.com/questions/47002485/removing-event-listener-in-react-lodash-throttle