有人可以帮我解决这个关于行为的问题吗,这是一个编写的代码片段
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 函数,但如果这是真的,顺序还会重要吗?
谢谢你
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]);