我如何解构来自 RTK 查询突变挂钩的错误?

How Can I Destructure error from is RTK Query Mutation Hook?

我正在使用 redux 工具包查询来获取数据 API。 问题是我遇到的是错误处理 redux 工具包 returns 来自查询挂钩的错误 属性。所以从服务器返回的错误是一个带有嵌套数据的对象以及试图访问它的内容我在尝试从错误对象访问数据时收到打字稿错误。

下面是我声明突变挂钩的方式

const [updateProgram, {
  isLoading: isUpdatingProgram,
  error: updateProgramError
}] = useUpdateProgramMutation();

下面是我如何尝试访问我的代码中的错误。

onSubmit = {
  async(values, {
    setSubmitting
  }) => {
    await updateProgram({ ...values,
      id: 'programData.data._id'
    });
    refetch();

    if (updateProgramError) {
      enqueueSnackbar('Test message', {
        variant: 'error'
      });
      console.log(updateProgramError?.data?.message);
    }
    setSubmitting(false);
  }
}

现在我得到的打字稿错误如下。 并不是说我能够 console.log(updateProgramError) 而是控制台中的数据

Property 'data' does not exist on type 'FetchBaseQueryError | SerializedError'.
  Property 'data' does not exist on type 'SerializedError'.
下面是我在控制台上整体登录时的 updateProgramError

{
  "status": 500,
  "data": {
    "status": "error",
    "message": "Something went very wrong!"
  }
}

下面是我如何实现 useUpdateProgramMutation()。

import { ndovuAPI } from './ndovuAPI';

export const ndovuProgramsAPI = ndovuAPI.injectEndpoints({
  endpoints: builder => ({
    getProgramById: builder.query({
      query: (id: string) => `/programs/${id}`,
      providesTags: ['Programs']
    }),
    getAllPrograms: builder.query({
      query: queryParams => ({ url: `/programs/`, params: queryParams }),
      providesTags: ['Programs']
    }),
    registerProgram: builder.mutation({
      query: body => ({
        url: '/programs',
        method: 'POST',
        body
      }),
      invalidatesTags: ['Programs']
    }),
    updateProgram: builder.mutation({
      query: body => ({ url: `/programs/${body.id}`, method: 'PATCH', body }),
      invalidatesTags: ['Programs']
    })
  }),
  overrideExisting: true
});

// Export hooks for usage in functional components
export const { useGetProgramByIdQuery, useGetAllProgramsQuery, useUpdateProgramMutation } = ndovuProgramsAPI;

从这个 TS 错误中我可以推断,updateProgramError 的类型似乎是类型 'FetchBaseQueryError''SerializedError' 和可能的其他类型的联合,这意味着 TS 仅假设您可以在确保 data 存在于对象中后安全地访问此 data 属性。

换句话说,TS 不知道 updateProgramError 是这些类型中的哪一种,除非您进行一些检查以确保这一点。

if (updateProgramError) {
  enqueueSnackbar('Test message', {
    variant: 'error'
  });
if ('data' in updateProgramError) console.log(updateProgramError.data.message);
}

您编写的代码不会按您想要的方式工作。您不能像那样从 onSubmit 处理程序内部的挂钩引用错误。您要做的是:

const onSubmit = async (values) => {
    try {
         // unwrapping will cause data to resolve, or an error to be thrown, and will narrow the types
        await updateProgram({ 
            ...values,
            id: 'programData.data._id'
        }).unwrap();
    // refetch(); // you should most likely just use tag invalidation here instead of calling refetch
    } catch (error) {
        // error is going to be `unknown` so you'll want to use a typeguard like:
        if (isMyKnownError(error)) { // add a typeguard like this
            enqueueSnackbar('Test message', {
                variant: 'error'
            });
        } else { 
        // You have some other error, handle it differently?
        }
    }
  }

参考文献: