使用 Redux Toolkit 调度多个异步操作

Chu*_*huy 4 reactjs react-native redux react-redux redux-toolkit

我正在使用 Expo/React Native 构建一个应用程序,并通过 Redux Toolkit 使用 Redux 来使用切片来处理应用程序的存储/状态。

我已经使用这个设置有一段时间了,没有出现任何复杂情况,因为我的功能很简单(例如用户/身份验证、购物车、类别和产品缩减器)。

但对于这个应用程序,我需要从单个端点加载多个目录。为了实现这一目标,我创建了一个“目录”切片,其中包含多个减速器和一个执行请求并根据目录名称分派减速器的操作。

const initialState = {
  catalogOne: [],
  catalogTwo: [],
  catalogThree: [],
  catalogN: []
}

const catalogsSlice = createSlice({
  name: "catalogs",
  initialState,
  reducers: {
    catalogOneRequestSucceeded: (state,action) => {
      state.catalogOne = action.payload
    },
    catalogTwoRequestSucceeded: (state,action) => {
      state.catalogTwo = action.payload
    },
    // ... and so on a reducer for each catalog
  }
});
Run Code Online (Sandbox Code Playgroud)

然后我有以下操作,用于请求具有目录名称的端点并调度减速器:

export const catalogRequest = (catalogName) => async (dispatch, getState) => {
  const state = getState();

  try {
    const rsp = await axios.get(`https://catalogEndpointBase/${catalogName}`, {
      headers: {
        Authorization: `Bearer ${state.user.accessToken}`,
        "Content-Type": "application/json",
      },
    });

    switch (catalogName) {
      case "catalogOne":
        dispatch(catalogOneRequestSucceeded(rsp.data));
        break;
      case "catalogTwo":
        dispatch(catalogTwoRequestSucceeded(rsp.data));
        break;
      case "catalogThree":
        dispatch(catalogThreeRequestSucceeded(rsp.data));
        break;
    }

    return rsp.data;
  } catch (e) {
    throw e;
  }
};
Run Code Online (Sandbox Code Playgroud)

所以我现在的问题是:如何以“异步/等待”方式多次分派此操作,以便目录依次加载?另外:我是否以正确的方式进行操作,或者是否有更好的方法来处理这种多重请求?

我正在考虑这样的事情,但我真的不知道如何实现:

  useEffect(() => {
    const loadCatalogsAsync = async() => {
      try {
        await dispatch(catalogRequest("catalogOne"));
        await dispatch(catalogRequest("catalogTwo"));
        await dispatch(catalogRequest("catalogThree"));
        // ... and so on for all my catalogs
      } catch ( e ) {
        console.error(e);
      }
    }

    loadCatalogsAsync();
  }, []);
}
Run Code Online (Sandbox Code Playgroud)

目标是为应用程序在加载时需要获取多个数据的行为找到最佳实践。

谢谢。

Lin*_*ste 5

你不需要awaitdispatch您也不需要 \xe2\x80\x99t 需要try/catch块,因为 thunk 将捕获任何 API 错误并调度 \xe2\x80\x9crejected\xe2\x80\x9d 操作。你可以只dispatch敲三声。

\n
useEffect(() => {\n  dispatch(catalogRequest("catalogOne"));\n  dispatch(catalogRequest("catalogTwo"));\n  dispatch(catalogRequest("catalogThree"));\n}, []);\n
Run Code Online (Sandbox Code Playgroud)\n
\n

我会把你的thunk和reducer写得更简单。我将使用一种操作类型并让其catalogName成为其中的一部分(您也可以从操作的属性payload访问它)。您可以删除thunk 中的meta整个块以及相应的大小写缩减器。switch相反,您可以使用一种 case 缩减器来根据 更新状态中的正确属性action.payload.catalogName

\n

重击:

\n
export const catalogRequest = createAsyncThunk(\n  "catalogs/request",\n  async (catalogName, { getState }) => {\n    const state = getState();\n    const rsp = await axios.get(`https://catalogEndpointBase/${catalogName}`, {\n      headers: {\n        Authorization: `Bearer ${state.user.accessToken}`,\n        "Content-Type": "application/json"\n      }\n    });\n    return {\n      data: rsp.data,\n      catalogName\n    };\n  }\n);\n
Run Code Online (Sandbox Code Playgroud)\n

片:

\n
const catalogsSlice = createSlice({\n  name: "catalogs",\n  initialState,\n  reducers: {},\n  extraReducers: {\n    [catalogRequest.fulfilled]: (state, action) => {\n      const { data, catalogName } = action.payload;\n      state[catalogName] = data;\n    }\n  }\n});\n
Run Code Online (Sandbox Code Playgroud)\n