reactjs - 如何通过 React Hook 使用 throttle 或去抖?

标签 reactjs lodash react-hooks throttling

我正在尝试在功能组件中使用 lodash 中的 throttle 方法,例如:

const App = () => {
  const [value, setValue] = useState(0)
  useEffect(throttle(() => console.log(value), 1000), [value])
  return (
    <button onClick={() => setValue(value + 1)}>{value}</button>
  )
}

由于每次渲染时都会重新声明useEffect内部的方法,因此限制效果不起作用。

有人有一个简单的解决方案(无需将 throttle 实现移到组件之外)吗?

最佳答案

过了一段时间后,我确信使用 setTimeout/clearTimeout 自己处理事情(并将其移动到单独的自定义 Hook 中)比使用功能助手要容易得多。在我们将其应用于 useCallback 后,处理后面的一个会带来额外的挑战,因为依赖项更改可以重新创建,但我们不想重置延迟运行。

原始答案如下

你可能(并且可能需要)useRef在渲染之间存储值。就像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 更改后重新创建回调:

const throttled = useCallback(throttle(() => console.log(value), 1000), [value]);

我们可能会发现它不会延迟执行:一旦发生更改,回调就会立即重新创建并执行。

所以我认为 useCallback 在延迟运行的情况下并没有提供显着的优势。这取决于你。

[UPD]最初是

  const throttled = useRef(throttle(() => console.log(value), 1000))

  useEffect(throttled.current, [value])

但是这样 throttled.current 通过闭包绑定(bind)到初始(0)。所以即使在下一次渲染中它也从未改变。

因此,由于闭包功能,在将函数插入 useRef 时要小心。

关于reactjs - 如何通过 React Hook 使用 throttle 或去抖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54666401/

相关文章:

javascript - Next.JS "Rendered more hooks than during the previous render"

reactjs - 如何在React中正确更新<select multiple ...>?

javascript - Lodash groupby 对象并组合数组

javascript - 在lodash中, `pairs()`的相反是什么?

javascript - Lodash - 检查对象是否包含数组中的任何键

javascript - useEffect 导致组件无限重新渲染

reactjs - react 钩子(Hook) : Display global spinner using axios interceptor?

javascript - 简单的 React.js 实现

javascript - React Hooks 中根据父组件的不同变化来更改子组件的不同 props?

javascript - React 内联样式不会影响我的自定义组件