You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么RTK Query的响应与错误处理未按预期工作?

问题原因分析

  • RTK Query的mutation触发函数返回的Promise默认不会抛错,始终返回一个包含data或error字段的对象,所以必须做字段判断才能拿到对应值,这是RTK Query的默认设计。你用到的transformResponse仅用来处理成功请求的返回值,不会修改mutation返回的包裹结构,所以不会省略掉data字段的判断步骤。
  • 你在Formik的onSubmit回调里直接读取hook返回的error和isError会碰到闭包陷阱:回调里存储的是组件初始渲染时的变量快照,请求完成后的最新状态还没触发组件重渲染,所以你拿到的永远是初始的undefined和false。
  • 你定义mutation的时候没有指定错误泛型,所以TS默认不知道你的错误结构是RequestError,才需要手动强转类型。

解决步骤

1. 给mutation指定错误泛型,避免强转

修改authRTK.ts里的login mutation定义,传入第三个泛型参数指定错误类型:

login: build.mutation<UserResponse, loginForm, { data: RequestError }>({
  query: (credentials) => ({
    url: "login",
    method: "POST",
    body: credentials
  }),
  transformResponse: (response: { data: UserResponse }) => {
    return response.data
  },
}),

2. 使用unwrap()直接获取响应数据/抛出错误

如果你不想每次都判断data字段,可以在调用login之后加.unwrap(),这样请求成功会直接返回data值,请求失败会抛出错误,你可以直接在catch里捕获错误:

onSubmit = {  async (values, actions) => {
  try{
    const result = await login(values).unwrap();
    // 这里直接拿成功数据,不用判断data字段
    console.log(result)
  }catch(err){
    // 这里直接拿到错误,类型已经是RequestError
    console.log(err.data)
  } 
}}

3. 如果你要使用hook返回的error、isError状态

不要在onSubmit回调里读取这些值,这些值需要在组件渲染的顶层读取,直接渲染到UI上:

const Login = () => {
  const [login, { isLoading, error, isError}] = useLoginMutation();
  const [showPassword,setShowPassword] = useState<boolean>(false);
  return (
    <Container>
      <Wrapper>
        <Title>SIGN IN</Title>
        {/* 直接在UI层使用错误状态 */}
        {isError && <Error>{(error as RequestError).data}</Error>}
        {/* 其余Formik代码保持不变 */}
      </Wrapper>
    </Container>
  )
}

内容的提问来源于stack exchange,提问作者Kai021195

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 04:24:05