如何使用 react-query 和 formik 处理服务器端错误?

How to handle server-side errors using react-query and formik?

这是我使用 formik 的登录页面:

const login = () => {
  const login = useLoginMutation();

  return (
    <div>
      <Formik
        initialValues={{ email: "", password: "" }}
        onSubmit={(values) => {
            login.mutate(values);
            console.log("isError", login.isError); \ it is false here
        }}
      >
        <Form>
          <FormInput name="email" label="email" />
          <FormInput name="password" label="password" />
          <button type="submit">submit</button>
        </Form>
      </Formik>
      <div>{login.isError && JSON.stringify(login?.error?.response.data)}</div> \ but here the login.isError is true
    </div>
  );
};

我想在 formik 中处理服务器端错误,所以我必须访问 onSubmit 事件中的错误。我希望错误在突变后可用,但如您所见,情况并非如此。

为了确保没有错误,我创建了一个 ‍‍div 元素来显示变异错误。出乎意料的是,这次竟然显示了所有的错误。

如何访问 onSubmit 中的突变错误?

login.mutate 是一个异步函数,您的 console.log 在评估 isError 之前实际上并没有等待突变解决。 react-query 提供了一个类似 mutate 的方法 mutateAsync returns 一个承诺解决突变的结果(或者如果有错误则抛出错误)。然后,您可以使用 async/await 和 try/catch 访问 onSubmit.

中的错误
   <Formik
     initialValues={{ email: "", password: "" }}
     onSubmit={async (values) => {
       try {
         const data = await mutation.mutateAsync(values)
         console.log(data) // data 
       } catch (error) {
         console.error(error) // error
       }
     }}
   >

login.isError的值只会在下一个渲染周期发生变化。如果您想在回调中直接访问它,有两种方法:

  1. mutate,你必须使用提供的 onErroronSuccess 回调,它获取作为参数传入的数据/错误:
onSubmit={(values) => {
  login.mutate(values, {
    onError: error => console.log(error),
    onSuccess: data => console.log(data),
  })
  1. 您可以改用 mutateAsync,这将 return data 或抛出错误,但请注意您必须自己进行错误处理,否则,您将结束未处理的承诺拒绝:
onSubmit={async (values) => {
  try {
    const data = await mutation.mutateAsync(values)
    console.log(data)
  } catch (error) {
    console.error(error)
}

除非你需要 returned Promise 来执行,例如同时进行多个突变并等待所有突变,我总是会选择 .mutate 和回调,但这是个人偏好。我只是觉得它更容易掌握,而且代码行数更少。