简体   繁体   English

redux-toolkit 在 createAsyncThunk 中获取很多数据

[英]redux-toolkit fetch many data in createAsyncThunk

I need function in redux-toolkit to fetch all data from others slices.我需要 function 在 redux-toolkit 中从其他切片中获取所有数据。

I have this code:我有这段代码:

export const getAllData = createAsyncThunk(
  'fetchRoot/getAllData',
  async (_, { dispatch, rejectWithValue }) => {
    const promises = [dispatch(getUsers()), dispatch(getSettings()), dispatch(getClients())];

    Promise.all(promises)
      .then((res: any) => {
        // for (const promise of res) {
        //  console.log('SSS', promise);
        //  if (promise.meta.rejectedWithValue) {
        //    return rejectWithValue(promise.payload);
        //  }
        }
      })
      .catch((err) => {
        console.log(err);
      });
  }
);

My question: if one of slice fetch function (example: getUsers()) is rejected, how to reject promise.all?我的问题:如果 slice fetch function(例如:getUsers())之一被拒绝,如何拒绝 promise.all?

getUsers() function and extraReducers: getUsers() function 和 extraReducers:

export const getUsers = createAsyncThunk('users/getUsers', async (_, { rejectWithValue }) => {
  try {
    const res = await agent.Users.getAll();
    return await res.data;
  } catch (err) {
    return rejectWithValue(err);
  }
});
  extraReducers: (builder) => {
    builder
      // GetUsers lifecycle ===================================
      .addCase(getUsers.pending, (state) => {
        state.apiState.loading = true;
        state.apiState.error = null;
      })
      .addCase(getUsers.fulfilled, (state, { payload }) => {
        state.apiState.loading = false;
        state.data = payload;
      })
      .addCase(getUsers.rejected, (state, { payload }) => {
        state.apiState.loading = false;
        state.apiState.error = payload;
      })

You have it basically right.你基本上是对的。 Once the Promise.all(promises) has resolved you will have an array containing the resolved value of each of your individual thunks.一旦Promise.all(promises)已解决,您将拥有一个包含每个单独 thunk 的已解决值的数组。

The individual promises will always resolve and will never reject.个人的承诺总是会解决并且永远不会拒绝。 They will resolve to either a fulfilled action or a rejected action.他们将解决一个已fulfilled的动作或一个rejected的动作。 In some cases, it will make sense to use the unwrap() property which causes rejected actions to throw errors.在某些情况下,使用unwrap()属性是有意义的,它会导致被拒绝的操作引发错误。 But looking at the .meta property will work too .但是查看.meta属性也可以

You can check your action with the isRejected or isRejectedWithValue functions which serve as type guards, that way you won't have any TypeScript errors when accessing properties like action.meta.rejectedWithValue .您可以使用用作类型保护的isRejectedisRejectedWithValue函数检查您的操作,这样在访问 action.meta.rejectedWithValue 等属性时就不会出现任何action.meta.rejectedWithValue错误。

The hard part here is trying to return rejectWithValue() from inside a loop.这里困难的部分是尝试从循环内部return rejectWithValue() I would recommend unwrapping to throw an error instead.我会建议展开以抛出错误。

import { createAsyncThunk, unwrapResult } from "@reduxjs/toolkit";

export const getAllData = createAsyncThunk(
  "fetchRoot/getAllData",
  async (_, { dispatch }) => {
    const promises = [dispatch(getUsers()), dispatch(getSettings()), dispatch(getClients())];

    const actions = await Promise.all(promises);
    return actions.map(unwrapResult);
  }
);

Note that there is no reason to try / catch in your getUsers thunk if you are going to rejectWithValue with the entire caught error object. Just let the error be thrown.请注意,如果您要rejectWithValue并捕获整个错误 object,则没有理由在您的getUsers thunk 中try / catch 。只需抛出错误即可。

export const getUsers = createAsyncThunk('users/getUsers', async () => {
  const res = await agent.Users.getAll();
  return res.data;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM