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

Why does RTK query response handling not work?

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

authRTK.ts

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { loginForm, UserResponse } from "../type/type";
import { RootState } from "./store";

export const api = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: 'http://localhost:3001',
    prepareHeaders: (headers, { getState }) => {
      // By default, if we have a token in the store, let's use that for authenticated requests
      const token = (getState() as RootState).auth.token;
      if (token) {
        headers.set("authentication", `Bearer ${token}`);
      }
      return headers;
    }
  }),
  endpoints: (build) => ({
    login: build.mutation<UserResponse, loginForm>({
      query: (credentials) => ({
        url: "login",
        method: "POST",
        body: credentials
      }),
      transformResponse: (response: { data: UserResponse }) => {
        return response.data
      },
    }),
    protected: build.mutation({
      query: () => "protected"
    })
  })
});

export const { useLoginMutation,useProtectedMutation } = api;

store.ts

import { configureStore } from '@reduxjs/toolkit'
import cartReducer from './cartRedux';
import userReducer from './authRedux';
import { api } from './authRTK';

export const store = configureStore({
    reducer:{
        cart: cartReducer,
        auth: userReducer,
        [api.reducerPath]: api.reducer,
    },
    middleware: (gDM) => gDM().concat(api.middleware),//getDefaultMiddleware
})

export type RootState = ReturnType<typeof store.getState>

export type AppDispatch = typeof store.dispatch

Login.tsx


const Login = () => {
  const [login, { isLoading,error,isError}] = useLoginMutation();
  const [showPassword,setShowPassword] = useState<boolean>(false);
  return (
    <Container>
      <Wrapper>
        {/* <button onClick={()=>testCookie()}>測試一下cookie</button> */}
        <Title>SIGN IN</Title>
        <Formik
          initialValues={{ email: "", password: "" }}
          validationSchema={Yup.object({
            password: Yup.string()
              .min(8, 'Must be 8 characters or higher')
              .required(),
            email: Yup.string().email('Invalid email address').required(),
          })}
          onSubmit = {  async (values, actions) => {
                try{
                  const result = await login(values);
                  if("data" in result){
                    console.log(result.data)
                  }else{
                    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
                    console.log(error) //This printout undefined,mean there's no error data inside,but not supposed to happen
                    console.log(isError) //print out false , but supposed to be true
                  }
                }catch(err){
                  console.log(err)
                } 
                
          }}>
            {({
            errors,
            values,
            handleChange,
            handleBlur,
            handleSubmit,
            validateField
          }) => (
            <Form onSubmit={handleSubmit}>
                <InputContainer>
                <Input
                  onChange={handleChange}
                  onBlur={handleBlur}
                  value={values.email}
                  type="text"
                  name="email"
                  placeholder="Email"
                  data-testid="email"
                />
                </InputContainer>
                {errors.email && <Error data-testid="emailError">{errors.email}</Error>}

                <InputContainer>
                <Input
                  onChange={handleChange}
                  onBlur={handleBlur}
                  value={values.password}
                  type={showPassword ? "text" : "password"}
                  name="password"
                  placeholder="Password"
                  data-testid="password"
                />
                {showPassword ? <VisibilityOff onClick={()=>setShowPassword(false) }/> : <Visibility onClick={()=>setShowPassword(true) }/> }
                </InputContainer>
                {errors.password && <Error data-testid="passwordError">{errors.password}</Error>}
                
              <Button 
              data-testid="submit"
              type="submit">Submit</Button>
            </Form>
          )}
        </Formik>
      </Wrapper>
    </Container>
  );
};

export default Login;

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

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

请求错误:

{
    data:string;
    status:string
}

data 不是您回复中的 data。即触发函数结果的data属性

trigger 始终 returns { 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)
                } 
                
          }