【问题标题】:how to modify the state of another slice from pending state of redux toolkit async thunk如何从 redux 工具包异步 thunk 的挂起状态修改另一个切片的状态
【发布时间】:2021-11-21 02:34:47
【问题描述】:

我正在构建一个简单的应用程序。我正在使用 redux 工具包进行状态管理

它必须查询数据库以检查用户是否经过身份验证。

如果是,它会为用户设置名称、电子邮件等

当它检查数据库时,我想在前端加载一个微调器,微调器占据整个屏幕,并在数据库查询时随时显示。出于这个原因,我想要一个单独的应用程序状态,它有两个值,即加载和错误

应用切片

const initialState = {loading : false,error:false,error_msg:null}
export const appSlice = createSlice({
    name : 'app',
    initialState : {value : initialState},
    reducers : {
        toggle : (state,action)=>{
            state.value.loading = action.payload
        }
    },
});

用户切片

const initialState = { name: "", email: "", role: "", isAuthenticated: false };
export const authenticateUser = createAsyncThunk(
  "user/authenticate",
  async () => {
    let res = await axiosInstance.get("/user/authenticate");
    return res.data;
  }
);
export const userSlice = createSlice({
  name: "user",
  initialState: { value: initialState },
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(authenticateUser.pending, (state, action) => {
      //change loading to true for app slice something like (state.app.loading = true)
    });
    builder.addCase(authenticateUser.fulfilled, (state, action) => {
      state.value = action.payload
    });
    builder.addCase(authenticateUser.rejected, (state, action) => {
      //change error to true for app slice something like (state.app.error = true)
      //change error_msg to action.payload for app slice 
      //something like (state.app.error_msg = action.payload)
    });
  },
});

【问题讨论】:

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


    【解决方案1】:

    您可以在不同的状态切片中处理一项操作。您应该从appSliceuserSlice 文件中引用authenticateUser.pendingauthenticateUser.rejected 动作创建者,并在appSliceextraReducers 中处理它们。

    例如,如果user/authenticate 操作因错误而失败。

    import { configureStore, createAsyncThunk, createSlice } from '@reduxjs/toolkit';
    
    export const authenticateUser = createAsyncThunk<any, any, { rejectValue: { error: string } }>(
      'user/authenticate',
      async (_, { rejectWithValue }) => {
        // success
        // return { name: 'teresa teng', email: 'teresa@gmail.com', role: 'admin', isAuthenticated: true };
        // fail
        return rejectWithValue({ error: 'network error' }) as unknown as { error: string };
      },
    );
    export const userSlice = createSlice({
      name: 'user',
      initialState: { value: { name: '', email: '', role: '', isAuthenticated: false } },
      reducers: {},
      extraReducers: (builder) => {
        builder.addCase(authenticateUser.fulfilled, (state, action) => {
          state.value = action.payload;
        });
      },
    });
    
    export const appSlice = createSlice({
      name: 'app',
      initialState: { value: { loading: false, error: false, error_msg: '' } },
      reducers: {
        toggle: (state, action) => {
          state.value.loading = action.payload;
        },
      },
      extraReducers: (builder) => {
        builder.addCase(authenticateUser.pending, (state, action) => {
          state.value.loading = true;
        });
        builder.addCase(authenticateUser.rejected, (state, action) => {
          state.value.error = true;
          state.value.error_msg = action.payload?.error || 'unknown error';
        });
      },
    });
    
    const store = configureStore({
      reducer: { app: appSlice.reducer, user: userSlice.reducer },
    });
    store.dispatch(authenticateUser({}));
    store.subscribe(() => {
      console.log(store.getState());
    });
    

    输出:

    {
      app: { value: { loading: true, error: true, error_msg: 'network error' } },
      user: { value: { name: '', email: '', role: '', isAuthenticated: false } }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      • 2022-12-31
      • 1970-01-01
      • 2016-09-22
      • 2017-10-23
      • 2022-12-11
      • 2020-11-17
      相关资源
      最近更新 更多