何时使用不带依赖项的 useEffect 与直接赋值?

Jon*_*ops 4 javascript reactjs react-hooks

我正在编写一个 React hook,允许我在我的组件中使用setInterval。为此,我需要将回调的最新版本保留在引用中,以便稍后可以从间隔的范围内访问它。

到目前为止,这是我的代码:

import { useRef, useEffect } from 'react'

export default function useInterval(
  callback: () => void,
  delay: number | null,
) {
  const callbackRef = useRef(callback)

  // Remember the latest callback.
  useEffect(() => {
    callbackRef.current = callback
  })

  useEffect(() => {
    // Don't schedule if no delay is specified.
    if (delay === null) {
      return
    }

    const id = setInterval(() => callbackRef.current(), delay)

    return () => clearInterval(id)
  }, [delay])
}
Run Code Online (Sandbox Code Playgroud)

useEffect我的问题是关于最新值传递给引用的第一个实例。根据 React 文档,此代码将在我的组件呈现后执行。

我可以想象,当您将引用传递给元素时,这很有用,这样您就可以确保它在呈现后具有值。但是,如果我的代码不关心组件何时呈现,那么将其保留在 a 中是否仍然有意义useEffect

我将代码重写如下是否有意义:

import { useRef, useEffect } from 'react'

export default function useInterval(
  callback: () => void,
  delay: number | null,
) {
  const callbackRef = useRef(callback)

  // Remember the latest callback.
  callbackRef.current = callback

  useEffect(() => {
    // Don't schedule if no delay is specified.
    if (delay === null) {
      return
    }

    const id = setInterval(() => callbackRef.current(), delay)

    return () => clearInterval(id)
  }, [delay])
}
Run Code Online (Sandbox Code Playgroud)

Aje*_*hah 8

何时使用useEffect无依赖项与直接赋值?

来自文档:

Effect Hook可让您在函数组件中执行副作用

  • useEffect没有依赖项(或作为依赖项)的 A将在第一次渲染和每次后续重新渲染undefined时运行,始终作为副作用,即在组件渲染之后。
  • 直接分配(同步操作)将在第一次渲染和每次后续重新渲染时运行,但始终与渲染周期中一样。它可能会影响性能或延迟渲染。

那么,什么时候使用哪一个呢?这取决于您的用例。

在此(有问题的)用例中使用哪一个?

我不会

useEffect(() => {
  callbackRef.current = callback
})
Run Code Online (Sandbox Code Playgroud)

也不

callbackRef.current = callback
Run Code Online (Sandbox Code Playgroud)

在这个用例中似乎是正确的。

因为我们不想callbackRef.current = callback在每次重新渲染时都进行分配。但我们希望在发生变化时这样做callback。所以,下面的似乎更好

useEffect(() => {
  callbackRef.current = callback
}, [callback])
Run Code Online (Sandbox Code Playgroud)

您可能会看到此博客相关帖子


一个演示,显示效果作为副作用运行(日志内部效果始终是最后一个):

useEffect(() => {
  callbackRef.current = callback
})
Run Code Online (Sandbox Code Playgroud)
callbackRef.current = callback
Run Code Online (Sandbox Code Playgroud)