如何通过 React Hook 使用油门或去抖动? [英] How to use throttle or debounce with React Hook?
问题描述
我正在尝试在功能组件中使用 lodash
中的 throttle
方法,例如:
I'm trying to use the throttle
method from lodash
in a functional component, e.g.:
const App = () => {
const [value, setValue] = useState(0)
useEffect(throttle(() => console.log(value), 1000), [value])
return (
<button onClick={() => setValue(value + 1)}>{value}</button>
)
}
由于 useEffect
内部的方法在每次渲染时重新声明,节流效果不起作用.
Since the method inside useEffect
is redeclared at each render, the throttling effect does not work.
有人有简单的解决方案吗?
Does anyone have a simple solution ?
推荐答案
经过一段时间后,我确信使用 setTimeout/clearTimeout
(并将其移入单独的自定义钩子)而不是使用功能助手.在我们将其应用到 useCallback
之后,稍后处理会带来额外的挑战,由于依赖项更改可以重新创建,但我们不想重置延迟运行.
After some time passed I'm sure it's much easier to handle things by your own with setTimeout/clearTimeout
(and moving that into separate custom hook) than working with functional helpers. Handling later one creates additional challenges right after we apply that to useCallback
that can be recreated because of dependency change but we don't want to reset delay running.
下面的原始答案
你可能(也可能需要)useRef
在渲染之间存储值.就像 建议定时器
类似的东西
const App = () => {
const [value, setValue] = useState(0)
const throttled = useRef(throttle((newValue) => console.log(newValue), 1000))
useEffect(() => throttled.current(value), [value])
return (
<button onClick={() => setValue(value + 1)}>{value}</button>
)
}
至于useCallback
:
它也可以作为
const throttled = useCallback(throttle(newValue => console.log(newValue), 1000), []);
但是如果我们尝试在 value
更改后重新创建回调:
But if we try to recreate callback once value
is changed:
const throttled = useCallback(throttle(() => console.log(value), 1000), [value]);
我们可能会发现它不会延迟执行:一旦 value
被更改,回调会立即重新创建并执行.
we may find it does not delay execution: once value
is changed callback is immediately re-created and executed.
所以我看到 useCallback
在延迟运行的情况下没有提供显着的优势.这取决于你.
So I see useCallback
in case of delayed run does not provide significant advantage. It's up to you.
[UPD] 最初是
const throttled = useRef(throttle(() => console.log(value), 1000))
useEffect(throttled.current, [value])
但是那样 throttled.current
已经通过闭包绑定到初始 value
(0).所以即使在下一次渲染中它也从未改变.
but that way throttled.current
has bound to initial value
(of 0) by closure. So it was never changed even on next renders.
因此在将函数推入 useRef
时要小心,因为有闭包特性.
So be careful while pushing functions into useRef
because of closure feature.
这篇关于如何通过 React Hook 使用油门或去抖动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!