📅  最后修改于: 2023-12-03 14:49:47.306000             🧑  作者: Mango
在 Redux Toolkit 中,有一个名为 AsyncThunk 的 API,它提供了一种方便的方式来处理异步操作。而使用 TypeScript 比 JavaScript 也更能帮助我们避免一些常见的错误。下面就让我们来介绍如何使用 TypeScript 来创建 AsyncThunk。
在开始之前,我们需要了解一些基本概念:
在 Redux 中,Thunk 是指一个指向另一个函数的函数。这个函数通常被用来延迟计算,或是在稍后的时间再执行。
举个例子,假设我们有这样一个异步的 Action Creator:
const fetchData = async (url: string) => {
const response = await fetch(url);
const data = await response.json();
return data;
};
const getData = (url: string) => async (dispatch: Dispatch) => {
dispatch({ type: 'FETCH_DATA_REQUEST' });
try {
const data = await fetchData(url);
dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data });
} catch (error) {
dispatch({ type: 'FETCH_DATA_FAILURE', payload: error });
}
};
注意,getData
返回的是一个函数,这个函数会接受一个 dispatch
函数。这个函数会在稍后的时候执行(在这个例子中,我们使用了 await
来确保 fetch 操作完成后再继续执行后续的代码)。
Thunk 的好处是可以让我们在 Action Creator 中发送异步请求,这样就避免了在组件中处理异步请求的麻烦。
AsyncThunk 是 Redux Toolkit 中的一个 API,它可以让我们更方便地创建异步 Action Creator。它的基本形式如下:
const myAsyncThunk = createAsyncThunk(
'myFeatureName/myAsyncThunk',
async (arg, thunkAPI) => {
// 异步请求代码
return result;
}
);
其中,createAsyncThunk
接受两个参数:
开始使用 TypeScript 来创建 AsyncThunk,我们首先需要安装必要的依赖:
npm install @reduxjs/toolkit react-redux @types/react-redux
接下来,我们就可以开始创建我们的 AsyncThunk 了。假设我们要从一个 API 获取用户信息,我们可以这样写:
import { createAsyncThunk } from '@reduxjs/toolkit';
import { User } from './types';
export const fetchUser = createAsyncThunk<User, string>('user/fetch', async (userId) => {
const response = await fetch(`/api/user/${userId}`);
return response.json();
});
这个例子中,我们定义了一个 fetchUser
的 AsyncThunk。它会接受一个 userId
参数,并且返回一个 User
。
我们可以从回调函数的签名来看一下 createAsyncThunk
的定义:
createAsyncThunk<Returned, ThunkArg = void, ThunkApiConfig = {}>(
typePrefix: string,
payloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg, ThunkApiConfig>
);
其中的 Returned
是我们期望异步请求返回的结果类型,也就是我们上述代码中的 User
。另外两个参数分别是 ThunkArg
和 ThunkApiConfig
。
如果我们不需要传递参数,我们可以这样写:
const fetchUser = createAsyncThunk<User>('user/fetch', async () => {
const response = await fetch('/api/user');
return response.json();
});
这种情况下,我们不需要传递额外的参数,所以 ThunkArg
的类型就是 void
。
如果我们需要在回调函数里访问到一些 Redux Toolkit 的额外功能,我们可以传递一个额外的配置对象。例如,我们可以指定请求成功时返回的 Action 中要包含的信息:
import { createAsyncThunk, SerializedError } from '@reduxjs/toolkit';
import { User } from './types';
interface MyThunkApiConfig {
rejectValue: {
data: null;
error: SerializedError;
};
}
export const fetchUser = createAsyncThunk<User, string, MyThunkApiConfig>('user/fetch', async (userId, thunkAPI) => {
const response = await fetch(`/api/user/${userId}`);
if (!response.ok) {
const error = await response.json();
return thunkAPI.rejectWithValue({ data: null, error });
}
return response.json();
}, {
rejectValue: {
data: null,
error: { name: '', message: '' },
},
});
这里我们传递了一个 MyThunkApiConfig
配置对象。我们在回调函数中可以使用 thunkAPI
的方法,例如 rejectWithValue
来处理请求失败的情况。同时我们还指定了一个默认的 rejectValue
。这个对象的类型可以在 @reduxjs/toolkit
的 SerializedError
中找到。
最后,我们需要将这个 AsyncThunk 添加到我们的 store 中:
import { configureStore } from '@reduxjs/toolkit';
import { fetchUser } from './userSlice';
export const store = configureStore({
reducer: {
user: userReducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(fetchUser.middleware),
});
注意我们需要使用 fetchUser.middleware
来把 AsyncThunk 加入到 store 的 middleware 中。
在 Redux Toolkit 中,使用 TypeScript 创建 AsyncThunk 非常简单。我们只需要使用 createAsyncThunk
API,就可以一步步地创建我们所需要的异步 Action Creator。同时,在 TypeScript 的帮助下,我们也可以更加方便地避免一些常见的错误。