如何在 React Hook 中使用节流阀或去抖动? [英] How to use throttle or debounce with React Hook?

查看:87
本文介绍了如何在 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 在渲染之间存储值.就像 建议用于计时器

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:

它也可以作为

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(of 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天全站免登陆