javascript - 无法使用 useState 挂钩限制功能
问题描述
我正在尝试使用我的 React 应用程序的 lodash 库来限制滚动时的事件“轮子”,但没有成功。
我需要从滚动输入中收听 e.deltaY 以检测其滚动方向。为了添加一个监听器,我编写了一个 React 钩子,它接受一个事件名称和一个处理函数。
基本实现
const [count, setCount] = useState(0);
const handleSections = () => {
setCount(count + 1);
};
const handleWheel = _.throttle(e => {
handleSections();
}, 10000);
useEventListener("wheel", handleWheel);
我的 useEventListener 钩子
function useEventListener(e, handler, passive = false) {
useEffect(() => {
window.addEventListener(e, handler, passive);
return function remove() {
window.removeEventListener(e, handler);
};
});
}
工作演示:https ://codesandbox.io/s/throttledemo-hkf7n
我的目标是限制此滚动事件,以减少触发事件并有几秒钟的时间以编程方式滚动我的页面(scrollBy()
例如,示例)。目前节流似乎不起作用,所以我一次得到了很多滚动事件
解决方案
当您可以调用_.throttle()
一个函数时,您将返回一个“管理”原始函数调用的新函数。每当调用包装器函数时,包装器都会检查是否经过了足够的时间,如果是,则调用原始函数。
如果_.throttle()
被多次调用,它会返回一个没有调用该函数的“历史”的新函数。然后它将一次又一次地调用原始函数。
在您的情况下,包装函数会在每次渲染时重新生成。_.throttle()
用useCallback
(沙箱)包装调用:
const { useState, useCallback, useEffect } = React;
function useEventListener(e, handler, cleanup, passive = false) {
useEffect(() => {
window.addEventListener(e, handler, passive);
return function remove() {
cleanup && cleanup(); // optional specific cleanup for the handler
window.removeEventListener(e, handler);
};
}, [e, handler, passive]);
}
const App = () => {
const [count, setCount] = useState(0);
const handleWheel = useCallback(_.throttle(() => {
setCount(count => count + 1);
}, 10000, { leading: false }), [setCount]);
useEventListener("wheel", handleWheel, handleWheel.cancel); // add cleanup to cancel throttled calls
return (
<div className="App">
<h1>Event fired {count} times</h1>
<h2>It should add +1 to cout once per 10 seconds, doesn't it?</h2>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
.App {
font-family: sans-serif;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
推荐阅读
- json - Log4j2 JSON 布局到 papertrails 日志记录
- python - Networkx 每次都在绘制不同的图表
- python - 选择数据框中的项目
- excel - 如何使用 PowerQuery 分步进行乘法运算?
- android-studio - 无法解析符号“onRadioButtonClicked”
- javascript - 如何将 Auth0 的 ID 令牌转发到 GraphQL 代码生成器?
- javascript - 如何将 CSS 添加到已清理的文本中?
- javascript - 如何在 vuex 中使用 FullCalendar
- python - Pyqt5 - 如何从辅助窗口返回隐藏的主窗口?
- javascript - 奇数/偶数 Javascript 值在回合之间不更新