📜  使用 typescript createasyncthunk(1)

📅  最后修改于: 2023-12-03 14:49:47.306000             🧑  作者: Mango

使用 TypeScript 创建 AsyncThunk

在 Redux Toolkit 中,有一个名为 AsyncThunk 的 API,它提供了一种方便的方式来处理异步操作。而使用 TypeScript 比 JavaScript 也更能帮助我们避免一些常见的错误。下面就让我们来介绍如何使用 TypeScript 来创建 AsyncThunk。

基本概念

在开始之前,我们需要了解一些基本概念:

Thunk

在 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

AsyncThunk 是 Redux Toolkit 中的一个 API,它可以让我们更方便地创建异步 Action Creator。它的基本形式如下:

const myAsyncThunk = createAsyncThunk(
  'myFeatureName/myAsyncThunk',
  async (arg, thunkAPI) => {
    // 异步请求代码
    return result;
  }
);

其中,createAsyncThunk 接受两个参数:

  • name:Action 的名字。会在 Redux DevTools 中使用。
  • asyncThunk:回调函数,包括异步代码和一些额外的信息。返回的结果会添加到 Payload Action 中。
使用 TypeScript

开始使用 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。另外两个参数分别是 ThunkArgThunkApiConfig

如果我们不需要传递参数,我们可以这样写:

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/toolkitSerializedError 中找到。

最后,我们需要将这个 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 的帮助下,我们也可以更加方便地避免一些常见的错误。