如何在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 fonctionnal 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
应用到由于依赖关系更改而可以重新创建的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
用于在渲染之间存储值.就像建议用于计时器
you may(and probably need) useRef
to store value between renders. Just like it's suggested for timers
类似的东西
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
:
As for 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屋!