【问题标题】:How to type error in createAsyncThunk with Axios如何使用 Axios 在 createAsyncThunk 中键入错误
【发布时间】:2021-11-16 21:15:10
【问题描述】:

我有一个关于使用 TypeScript 处理 createAsyncThunk 中的错误的问题。

我用泛型声明了返回类型和参数类型。但是,我尝试处理错误输入,但最终只使用了“任何”。

这里是 api/todosApi.ts...

import axios from 'axios';

export const todosApi = {
    getTodosById
}

// https://jsonplaceholder.typicode.com/todos/5
function getTodosById(id: number) {
    return instance.get(`/todos/${id}`);
}

// -- Axios
const instance = axios.create({
    baseURL: 'https://jsonplaceholder.typicode.com'
})

instance.interceptors.response.use(response => {
    return response;
}, function (error) {
    if (error.response.status === 404) {
        return { status: error.response.status };
    }
    return Promise.reject(error.response);
});

function bearerAuth(token: string) {
    return `Bearer ${token}`
}

这里是 todosActions.ts

import { createAsyncThunk } from '@reduxjs/toolkit'
import { todosApi } from '../../api/todosApi'

export const fetchTodosById = createAsyncThunk<
    {
        userId: number;
        id: number;
        title: string;
        completed: boolean;
    },
    { id: number }
>('todos/getTodosbyId', async (data, { rejectWithValue }) => {
    try {

        const response = await (await todosApi.getTodosById(data.id)).data
        return response
    // typescript infer error type as 'unknown'. 
    } catch (error: any) {
        return rejectWithValue(error.response.data)
    }
})

这是 todosSlice.ts

import { createSlice } from '@reduxjs/toolkit'
import { fetchTodosById } from './todosActions'

interface todosState {
    todos: {
        userId: number;
        id: number;
        title: string;
        completed: boolean;
    } | null,
    todosLoading: boolean;
    todosError: any | null; // I end up with using any
}

const initialState: todosState = {
    todos: null,
    todosLoading: false,
    todosError: null
}

const todosSlice = createSlice({
    name: 'todos',
    initialState,
    reducers: {

    },
    extraReducers: (builder) => {
        builder
            .addCase(fetchTodosById.pending, (state) => {
                state.todosLoading = true
                state.todosError = null
            })
            .addCase(fetchTodosById.fulfilled, (state, action) => {
                state.todosLoading = false
                state.todos = action.payload
            })
            .addCase(fetchTodosById.rejected, (state, action) => {
                state.todosLoading = false
                state.todosError = action.error
            })


    }
})

export default todosSlice.reducer;

此外,我的代码似乎没有捕获 4xx 错误。是不是因为我在 todosApi 中的 getTodosById 没有抛出错误?

我对 TypeScript 没有太多经验,所以请原谅我的无知。

更新:我设法处理了不使用“任何”类型的错误,但我不知道我是否做得对。

//todosActions..
export const fetchTodosById = createAsyncThunk<
    {
        userId: number;
        id: number;
        title: string;
        completed: boolean;
    },
    number
>('todos/getTodosbyId', async (id, { rejectWithValue }) => {
    const response = await todosApi.getTodosById(id);
    if (response.status !== 200) {
        return rejectWithValue(response)
    }
    return response.data
})

// initialState...
todosError: SerializedError | null;

【问题讨论】:

    标签: reactjs typescript redux axios redux-toolkit


    【解决方案1】:

    这在Usage with TypeScript 文档页面中有描述:

    const fetchUserById = createAsyncThunk<
      // Return type of the payload creator
      MyData,
      // First argument to the payload creator
      number,
      {
        // Optional fields for defining thunkApi field types
        rejectValue: YourAxiosErrorType
      }
    >('users/fetchById', async (userId, thunkApi) => {
      // ...
    })
    

    【讨论】:

      猜你喜欢
      • 2020-12-18
      • 2022-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多