如何通过 React Hook 使用油门或去抖动? [英] How to use throttle or debounce with React Hook?

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

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