反应警告 useEffect 缺少依赖项
React warning useEffect missing dependency
在我的 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 将 "watch" 的值,一旦发生任何更改,组件将重新渲染(类似于 componentDidUpdate
的工作方式)...
虽然在我的 useEffect
调用中使用了其他值,但我只想在 user.client.id
或 user.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
的正确方法是什么?
要么将所有依赖添加到数组
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]);
或者它可能只是被你的 react-hooks linter 标记,你可以为该行禁用它。
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]);
我通常也会在覆盖上方留下评论,说明它的原因。请谨慎使用此选项,因为当您对效果挂钩进行任何更改时,它会更改您希望挂钩更改的内容 "watch"。
建议:将 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]);
要在依赖列表中包含 loadFileds
函数,请尝试用 React.useCallback
挂钩将其包装起来
React.useCallback(async (clientId, token) => { ... }, []);
并将其添加到依赖列表。 useCallback
"remembers" 函数并且不会在每次渲染时都创建它,因此 loadFields
在渲染中保持相同并且不会触发 effect
,参见 Documentation.
那么 tokenExpiry
- 好吧,有时会发生这种情况,我通常会发表评论,描述为什么某些变量不在依赖列表中。
在我的 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 将 "watch" 的值,一旦发生任何更改,组件将重新渲染(类似于 componentDidUpdate
的工作方式)...
虽然在我的 useEffect
调用中使用了其他值,但我只想在 user.client.id
或 user.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
的正确方法是什么?
要么将所有依赖添加到数组
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]);
或者它可能只是被你的 react-hooks linter 标记,你可以为该行禁用它。
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]);
我通常也会在覆盖上方留下评论,说明它的原因。请谨慎使用此选项,因为当您对效果挂钩进行任何更改时,它会更改您希望挂钩更改的内容 "watch"。
建议:将 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]);
要在依赖列表中包含 loadFileds
函数,请尝试用 React.useCallback
挂钩将其包装起来
React.useCallback(async (clientId, token) => { ... }, []);
并将其添加到依赖列表。 useCallback
"remembers" 函数并且不会在每次渲染时都创建它,因此 loadFields
在渲染中保持相同并且不会触发 effect
,参见 Documentation.
那么 tokenExpiry
- 好吧,有时会发生这种情况,我通常会发表评论,描述为什么某些变量不在依赖列表中。