为什么 RTK 查询响应处理不起作用?

Kai*_*195 5 react-redux rtk-query

我尝试在登录请求中使用 RTK 查询,但在打印结果时遇到了一些问题。这是我的代码。

\n

authRTK.ts

\n
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";\nimport { loginForm, UserResponse } from "../type/type";\nimport { RootState } from "./store";\n\nexport const api = createApi({\n  baseQuery: fetchBaseQuery({\n    baseUrl: \'http://localhost:3001\',\n    prepareHeaders: (headers, { getState }) => {\n      // By default, if we have a token in the store, let\'s use that for authenticated requests\n      const token = (getState() as RootState).auth.token;\n      if (token) {\n        headers.set("authentication", `Bearer ${token}`);\n      }\n      return headers;\n    }\n  }),\n  endpoints: (build) => ({\n    login: build.mutation<UserResponse, loginForm>({\n      query: (credentials) => ({\n        url: "login",\n        method: "POST",\n        body: credentials\n      }),\n      transformResponse: (response: { data: UserResponse }) => {\n        return response.data\n      },\n    }),\n    protected: build.mutation({\n      query: () => "protected"\n    })\n  })\n});\n\nexport const { useLoginMutation,useProtectedMutation } = api;\n
Run Code Online (Sandbox Code Playgroud)\n

商店.ts

\n
import { configureStore } from \'@reduxjs/toolkit\'\nimport cartReducer from \'./cartRedux\';\nimport userReducer from \'./authRedux\';\nimport { api } from \'./authRTK\';\n\nexport const store = configureStore({\n    reducer:{\n        cart: cartReducer,\n        auth: userReducer,\n        [api.reducerPath]: api.reducer,\n    },\n    middleware: (gDM) => gDM().concat(api.middleware),//getDefaultMiddleware\n})\n\nexport type RootState = ReturnType<typeof store.getState>\n\nexport type AppDispatch = typeof store.dispatch\n
Run Code Online (Sandbox Code Playgroud)\n

登录.tsx

\n
\nconst Login = () => {\n  const [login, { isLoading,error,isError}] = useLoginMutation();\n  const [showPassword,setShowPassword] = useState<boolean>(false);\n  return (\n    <Container>\n      <Wrapper>\n        {/* <button onClick={()=>testCookie()}>\xe6\xb8\xac\xe8\xa9\xa6\xe4\xb8\x80\xe4\xb8\x8bcookie</button> */}\n        <Title>SIGN IN</Title>\n        <Formik\n          initialValues={{ email: "", password: "" }}\n          validationSchema={Yup.object({\n            password: Yup.string()\n              .min(8, \'Must be 8 characters or higher\')\n              .required(),\n            email: Yup.string().email(\'Invalid email address\').required(),\n          })}\n          onSubmit = {  async (values, actions) => {\n                try{\n                  const result = await login(values);\n                  if("data" in result){\n                    console.log(result.data)\n                  }else{\n                    console.log((result.error as RequestError).data) ////this will printout the expected result , but I have to cast error to RequestError type to print the nested data inside , and I can\'t use this data else where like error above\n                    console.log(error) //This printout undefined,mean there\'s no error data inside,but not supposed to happen\n                    console.log(isError) //print out false , but supposed to be true\n                  }\n                }catch(err){\n                  console.log(err)\n                } \n                \n          }}>\n            {({\n            errors,\n            values,\n            handleChange,\n            handleBlur,\n            handleSubmit,\n            validateField\n          }) => (\n            <Form onSubmit={handleSubmit}>\n                <InputContainer>\n                <Input\n                  onChange={handleChange}\n                  onBlur={handleBlur}\n                  value={values.email}\n                  type="text"\n                  name="email"\n                  placeholder="Email"\n                  data-testid="email"\n                />\n                </InputContainer>\n                {errors.email && <Error data-testid="emailError">{errors.email}</Error>}\n\n                <InputContainer>\n                <Input\n                  onChange={handleChange}\n                  onBlur={handleBlur}\n                  value={values.password}\n                  type={showPassword ? "text" : "password"}\n                  name="password"\n                  placeholder="Password"\n                  data-testid="password"\n                />\n                {showPassword ? <VisibilityOff onClick={()=>setShowPassword(false) }/> : <Visibility onClick={()=>setShowPassword(true) }/> }\n                </InputContainer>\n                {errors.password && <Error data-testid="passwordError">{errors.password}</Error>}\n                \n              <Button \n              data-testid="submit"\n              type="submit">Submit</Button>\n            </Form>\n          )}\n        </Formik>\n      </Wrapper>\n    </Container>\n  );\n};\n\nexport default Login;\n
Run Code Online (Sandbox Code Playgroud)\n

所以我的主要问题是login.tsx,错误没有按预期工作,并且我的响应数据必须确定“数据”是否在其中,即使我使用了transformResponse。

\n

顺便说一句,我的回复类型如下所示

\n

请求错误:

\n
{\n    data:string;\n    status:string\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

phr*_*hry 9

data不是data你的回复。它是data触发函数结果的属性。

trigger 始终{ data: ... }返回或形式的对象{ error: ... }

因此,如果没有你的transformResult,你最终会得到result.data.data而不是result.data.

您还可以解开它,直接获取数据并在错误情况下抛出错误,但这不是默认设置,因为如果您不处理它,可能会导致未捕获的承诺拒绝错误。

async (values, actions) => {
                try{
                  const result = await login(values).unwrap();
                  console.log(result.data)
                } catch(err){
                  console.log(err)
                } 
                
          }
Run Code Online (Sandbox Code Playgroud)