反应警告使用效果缺少依赖项



在我的 React 应用程序中,我有一个 redux 存储,其中包含具有以下模型的用户:

{
id: "",
name: "",
email: "",
isAdmin: false,
client: { id: undefined },
token: "",
tokenExpiry: null
};

在一个简单的页面上,我正在查询数据库中与该用户关联的其他数据。为此,我正在利用useEffect钩子:

useEffect(() => {
// Check JWT auth token and refresh if near expiry
auth.refresh(
{ token: user.token, tokenExpiry: user.tokenExpiry },
// Request user "field" data
loadFields(user.client.id, user.token)
);
}, [user.client.id, user.token]);

在构建时,React 会发出React Hook useEffect has missing dependencies: 'loadFields' and 'user.tokenExpiry'. Either include them or remove the dependency array警告。

如果我理解正确useEffect,第二个参数是 Reach 将"监视"的值,在任何更改时,组件将被重新渲染(类似于componentDidUpdate的工作方式(......

虽然我的useEffect调用中使用了其他值,但我只想在更改user.client.iduser.token时重新处理此函数。这是为了避免在更改用户模型的其他部分时进行不必要的重新渲染,因此我不想添加user.tokenExpiry作为依赖项。

由于loadFields函数也是在useEffect逻辑之外使用的函数,因此我无法将其放置在useEffect中,因此我尝试将其添加为依赖项,但这会导致重新渲染循环,因为它在其中具有dispatch调用:

const loadFields = async (clientId, token) => {
setIsLoading(true);
try {
await dispatch(fetchFields(clientId, token));
setIsLoading(false);
} catch (error) {
setIsLoading(false);
dispatch(resetFields());
}
};

那么在这种情况下,useEffect的正确方法是什么?

要在依赖项列表中包含loadFileds函数,请尝试像这样用React.useCallback钩子包装它

React.useCallback(async (clientId, token) => { ... }, []);

并将其添加到依赖项列表中。useCallback"记住"函数并且不会在每次渲染时创建它,因此loadFields渲染之间保持不变,并且不会触发effect,请参阅文档。

tokenExpiry呢 - 好吧,有时会发生这种情况,我通常会发表评论,描述为什么某些变量不在依赖项列表中。

将所有依赖项添加到数组中

useEffect(() => {
// Check JWT auth token and refresh if near expiry
auth.refresh(
{ token: user.token, tokenExpiry: user.tokenExpiry },
// Request user "field" data
loadFields(user.client.id, user.token)
);
}, [user.client.id, user.token, user.tokenExpiry]);

或者它可能只是被你的反应钩子标记,你可以为那一行禁用它。

useEffect(() => {
// Check JWT auth token and refresh if near expiry
auth.refresh(
{ token: user.token, tokenExpiry: user.tokenExpiry },
// Request user "field" data
loadFields(user.client.id, user.token)
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user.client.id, user.token]);

我通常也会在覆盖上方留下评论,以了解其原因。请谨慎使用,因为当您对效果钩子进行任何更改时,它可能会更改您希望钩子"监视"更改的内容。

建议:将tokenExpry添加到数组,如果可以判断出终结点接近需要刷新,则有条件地调用终结点。

useEffect(() => {
// Check JWT auth token and refresh if near expire
if ( /* tokenExpiry almost expired */ ) {
auth.refresh(
{ token: user.token, tokenExpiry: user.tokenExpiry },
// Request user "field" data
loadFields(user.client.id, user.token)
);
}
}, [user.client.id, user.token, user.tokenExpiry]);

相关内容

  • 没有找到相关文章

最新更新