useMutation 完成后如何更新 React 状态?

时间:2021-02-14 11:21:09

标签: reactjs react-query

我使用 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

1 个答案:

答案 0 :(得分:2)

success 返回的 updateUser 道具(我假设这是 useMutation 返回的结果)只会在下一个渲染周期更新。函数仍然会保留对它们关闭的任何内容的引用,即使你在那里有一个异步等待。这与 react-query 无关,这就是 react 的工作原理。

我建议使用突变函数的 onSuccess 回调,或者使用 mutateAsync 并检查结果,但您必须记住,如果您使用 {{1} }.您可以阅读有关 mutateAsync here 的文章,我将向您展示一个 mutateAsync 示例:

mutate

另外,请不要违反钩子的规则。您只能从功能组件或其他钩子(=以 const { mutate, loading } = useMutation(() => ...); const onAddUser = () => mutate(newUser, { onSuccess: (newData) => setUsers((users) => [...users, data]); }); }; 开头的函数)中调用钩子,但在您的代码和框中,您可以从 use 函数中调用 useMutation ...