我有一个钩子,可使用滚轮或keyup
事件在React应用程序中更改页面。最后,我来到了这个有效的解决方案:
function useScrollingPage (pages) {
const [page, setPage] = useState(0);
const wheelHandler = (event) => {
// some logic
setPage(page + 1);
};
useEffect(
() => {
window.addEventListener(EVENTS.WHEEL, wheelHandler);
window.addEventListener(EVENTS.KEY_UP, keyHandler);
return () => {
window.removeEventListener(EVENTS.WHEEL, wheelHandler);
window.removeEventListener(EVENTS.KEY_UP, keyHandler);
};
},
[page],
);
return page;
}
但是,在处理它时,我遇到了几次迭代。
addEventListener
之外给useEffect
打电话。这样,一切正常,但是侦听器永远不会被删除。useEffect
的第二个参数。这样,它只能在组件安装上运行,但不会更改page
中的wheelHandler
引用,因此它将始终尝试将页面设置为1(setPage(0 + 1)
)page
更改时都运行useEffect。它可以工作,但是每次状态更改时都删除并添加所有侦听器并不恰当。每次状态更改时添加/删除事件侦听器对性能是否有害?像这样的问题的最佳解决方案是什么?
答案 0 :(得分:0)
根据文档,当侦听器依赖状态或要订阅的道具时,您可能希望使用上述模式,但是在上述情况下,您可以使用状态更新的回调模式并传递一个空数组作为useEffect
function useScrollingPage (pages) {
const [page, setPage] = useState(0);
const wheelHandler = (event) => {
// some logic
setPage(page => page + 1);
};
useEffect(
() => {
window.addEventListener(EVENTS.WHEEL, wheelHandler);
window.addEventListener(EVENTS.KEY_UP, keyHandler);
return () => {
window.removeEventListener(EVENTS.WHEEL, wheelHandler);
window.removeEventListener(EVENTS.KEY_UP, keyHandler);
};
},
[],
);
return page;
}
但是,当您编写上述逻辑时,请确保未在wheelHandler中使用状态。如果是这样,那么您将遵循适合您的模式并建议这样做。