【问题标题】:Dispatch multiple async actions with Redux Toolkit使用 Redux Toolkit 调度多个异步操作
【发布时间】:2021-07-09 23:49:06
【问题描述】:

我正在使用 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
  }
});

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

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;
  }
};

所以我现在的问题是:如何以“异步/等待”方式多次分派此操作,以便一个接一个地加载目录?还有:我的做法是正确的还是有更好的方法来处理这种多重请求?

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

  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();
  }, []);
}

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

谢谢。

【问题讨论】:

    标签: reactjs react-native redux react-redux redux-toolkit


    【解决方案1】:

    您不需要await dispatch。您也不需要 try/catch 块,因为 thunk 将捕获任何 API 错误并调度“拒绝”操作。你可以只 dispatch 你的三个 thunk。

    useEffect(() => {
      dispatch(catalogRequest("catalogOne"));
      dispatch(catalogRequest("catalogTwo"));
      dispatch(catalogRequest("catalogThree"));
    }, []);
    

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

    重击:

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

    切片:

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

    【讨论】:

      猜你喜欢
      • 2023-04-05
      • 2020-01-17
      • 2021-07-27
      • 1970-01-01
      • 2016-09-23
      • 2016-08-21
      • 2017-07-18
      • 2021-08-29
      • 2020-12-28
      相关资源
      最近更新 更多