useMutation 完成后如何更新 React 状态?
How to update React state once useMutation is done?
我使用 react-query 的 useMutation 挂钩将用户添加到 api。有用。现在,我需要将新用户添加到我的状态下的用户数组中。
我知道我应该使用 useQuery 查询所有用户,然后在 useMutation 中使用 onSuccess 来修改缓存。但在某些情况下,我不会使用 useQuery 获取用户,因此我需要更新本地状态,就像我在正常承诺中所做的那样。
目前,我只是检查道具“成功”是否为真,如果是,我更新数组。但它只适用于第二次点击。为什么以及如何解决这个问题?
onAddUser() 中的成功条件似乎只有在第二次点击时才能达到。
export default function App() {
const { updateUser } = userService();
const { update, loading, error, data, success } = updateUser();
const [users, setUsers] = useState(allUsers);
const onAddUser = async () => {
await update(newUser);
if (success) {
return setUsers((users) => [...users, data]);
}
};
return (
<>
<div>
{users.map((user) => (
<div key={user.id}>
{user.name} - {user.job}
</div>
))}
</div>
{loading && <div>sending...</div>}
{error && <div>error</div>}
<button onClick={() => onAddUser()}>add user</button>
</>
);
}
这里还有一个沙箱:https://codesandbox.io/s/usemutation-test-co7e9?file=/src/App.tsx:283-995
从 updateUser
返回的 success
道具(我假设这是 useMutation 以某种方式返回的结果)只会在下一个渲染周期更新。函数仍然会保留对它们关闭的任何内容的引用,即使你在那里有一个异步等待。这不是特定于反应查询的,这就是反应的工作原理。
我建议使用突变函数的 onSuccess
回调,或使用 mutateAsync
并检查结果,但如果使用 [= 则必须记住手动捕获错误14=]。您可以阅读 mutateAsync
here,我将向您展示一个 mutate
示例:
const { mutate, loading } = useMutation(() => ...);
const onAddUser = () =>
mutate(newUser, {
onSuccess: (newData) => setUsers((users) => [...users, data]);
});
};
另外,请不要违反hooks的规则。您只能从功能组件或其他钩子(=以 use
开头的函数)调用钩子,但在您的 codesandbox 中,您从 updateUser
函数调用 useMutation
...
我使用 react-query 的 useMutation 挂钩将用户添加到 api。有用。现在,我需要将新用户添加到我的状态下的用户数组中。
我知道我应该使用 useQuery 查询所有用户,然后在 useMutation 中使用 onSuccess 来修改缓存。但在某些情况下,我不会使用 useQuery 获取用户,因此我需要更新本地状态,就像我在正常承诺中所做的那样。
目前,我只是检查道具“成功”是否为真,如果是,我更新数组。但它只适用于第二次点击。为什么以及如何解决这个问题?
onAddUser() 中的成功条件似乎只有在第二次点击时才能达到。
export default function App() {
const { updateUser } = userService();
const { update, loading, error, data, success } = updateUser();
const [users, setUsers] = useState(allUsers);
const onAddUser = async () => {
await update(newUser);
if (success) {
return setUsers((users) => [...users, data]);
}
};
return (
<>
<div>
{users.map((user) => (
<div key={user.id}>
{user.name} - {user.job}
</div>
))}
</div>
{loading && <div>sending...</div>}
{error && <div>error</div>}
<button onClick={() => onAddUser()}>add user</button>
</>
);
}
这里还有一个沙箱:https://codesandbox.io/s/usemutation-test-co7e9?file=/src/App.tsx:283-995
从 updateUser
返回的 success
道具(我假设这是 useMutation 以某种方式返回的结果)只会在下一个渲染周期更新。函数仍然会保留对它们关闭的任何内容的引用,即使你在那里有一个异步等待。这不是特定于反应查询的,这就是反应的工作原理。
我建议使用突变函数的 onSuccess
回调,或使用 mutateAsync
并检查结果,但如果使用 [= 则必须记住手动捕获错误14=]。您可以阅读 mutateAsync
here,我将向您展示一个 mutate
示例:
const { mutate, loading } = useMutation(() => ...);
const onAddUser = () =>
mutate(newUser, {
onSuccess: (newData) => setUsers((users) => [...users, data]);
});
};
另外,请不要违反hooks的规则。您只能从功能组件或其他钩子(=以 use
开头的函数)调用钩子,但在您的 codesandbox 中,您从 updateUser
函数调用 useMutation
...