如何在React Hook中使用油门或反跳? [英] How to use throttle or debounce with React Hook?

查看:345
本文介绍了如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆