当 useEffect 和 useCallback 具有相同的 dep 时,它们会起作用吗?

问题描述 投票:0回答:1

有人可以帮我解决这个关于行为的问题吗,这是一个编写的代码片段

const [accountId, setAccountId] = useState(null);
  // accountId gets set in code not shown here

  const makeAsyncNetworkCall = useCallback(async () => {
    const response = await get(buildUrl(url, accountId));

    if (response.ok) {
      return response.data;
    }

    return [];
  }, [accountId]);

  useEffect(() => {
    if (accountId) {
      // do some extra work here
    }

    makeAsyncNetworkCall()
        .then(response => {
          // handle response
        })
        .catch(() => {
          // handle error
        });
  }, [accountId]);

我希望代码是正确的,因为我做得很快。所以我知道,使用 useEffect,如果 deps (在本例中是 accountId)发生任何变化,那么它将运行回调中的内容。但是,将一些代码转换为使用 useCallbacks 而不是没有它们的函数,我想知道当 useeffect 调用 usecallback 函数时,当两者在 dep 中具有相同的状态时,行为如何?

我的猜测是,当 useCallback 中的 deps 发生变化时,它将重新渲染函数(并限制 in 中的任何变量,(在 use 回调之前,我在这里有停顿状态))。 useeffect deps 将触发调用 useCallback 函数,但如果这是真的,顺序还会重要吗?

谢谢你

reactjs react-hooks
1个回答
0
投票

useEffect
钩子的用途与
useCallback
不同。

useEffect
useCallback
用于发出有意的副作用 用于记忆并提供稳定的回调参考
当任何依赖项发生更改时,会调用钩子回调,从而产生副作用 当任何依赖项发生更改时,都会调用钩子回调,返回一个记忆的回调函数,以用作其他钩子的依赖项或作为优点传递下来

我在实现中看到的问题是

useCallback
钩子将正确包含更新的
accountId
值并创建稳定的回调函数,但由于
makeAsyncNetworkCall
被从
useEffect
钩子的依赖数组中省略,效果回调将永远不会得到它的更新“副本”。

要么将所有逻辑移至`useEffe

const [accountId, setAccountId] = useState(null);
  
useEffect(() => {
  if (accountId) {
    // do some extra work here
  }

  get(buildUrl(url, accountId))
    .then(response => {
      // handle response
    })
    .catch(() => {
      // handle error
    });
}, [accountId]);

或者在

makeAsyncNetworkCall
依赖数组中指定
useEffect

const [accountId, setAccountId] = useState(null);

const makeAsyncNetworkCall = useCallback(async () => {
  const response = await get(buildUrl(url, accountId));

  if (response.ok) {
    return response.data;
  }

  return [];
}, [accountId]);

useEffect(() => {
  if (accountId) {
    // do some extra work here
  }

  makeAsyncNetworkCall()
    .then(response => {
      // handle response
    })
    .catch(() => {
      // handle error
    });
}, [accountId, makeAsyncNetworkCall]);
© www.soinside.com 2019 - 2024. All rights reserved.