小编典典

如何在React Hook中使用油门或反跳?

reactjs

我正在尝试throttlelodash功能组件中使用该方法,例如:

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

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

有没有人有一个简单的解决方案?


阅读 338

收藏
2020-07-22

共1个答案

小编典典

经过一段时间后,我相信setTimeout/clearTimeout使用功能性助手(并将其移动到单独的自定义挂钩中)比使用功能性助手要容易得多。在稍后处理一个挑战之后,我们立即将其应用到useCallback由于依赖关系更改而可以重新创建的挑战中,但是我们不想重置延迟运行。

下面的原始答案

您可能(可能需要)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更改:

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

我们可能会发现它不会延迟执行:value更改后,回调将立即重新创建并执行。

因此,我发现useCallback在延迟运行的情况下不会提供明显的优势。由你决定。

[UPD]最初是

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

  useEffect(throttled.current, [value])

但是这种方式throttled.current已经value通过闭包绑定到初始(0)。因此,即使在下一个渲染中也从未改变过。

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

2020-07-22