27

Redux 工具包文档提到在多个 reducer 中使用操作(或者更确切地说是操作类型)

首先,Redux 操作类型并不意味着对单个切片是专有的。从概念上讲,每个 slice reducer “拥有”它自己的 Redux 状态,但它应该能够监听任何动作类型并适当地更新其状态。例如,许多不同的切片可能希望通过清除数据或重置回初始状态值来响应“用户注销”操作。在设计状态形状和创建切片时请记住这一点。

但是,“记住这一点” ,鉴于工具包将切片名称放在每个动作类型的开头,实现这一点的最佳方法是什么?并且您从该切片中导出一个函数并调用该单个函数来调度操作?我错过了什么?这是否必须以某种不使用的方式完成createSlice

4

2 回答 2

21

看起来这就是extraReducers的用途:

Redux 的一个关键概念是每个 slice reducer “拥有”它的 state slice,并且许多 slice reducer 可以独立地响应相同的 action 类型。extraReducers 允许 createSlice 响应除了它生成的类型之外的其他动作类型。

动作调度器应该知道动作属于哪个reducer,这有点奇怪。我不确定拥有的动机,reducers 但是 extraReducers,您可以使用它extraReducers来允许多个切片响应相同的操作。

于 2020-06-07T03:09:50.730 回答
0

我发现extraReducers在创建切片时使用该功能createSlice是最好的方法。

就我而言,我通过为每个相关功能创建一个“SliceFactory”类来实现这一点。我已经使用它来完全执行示例中的操作,并通过侦听LOGOUT_USER操作来重置用户注销时的相关切片。

参考

extraReducers:https ://redux-toolkit.js.org/api/createSlice#extrareduce

我用于工厂的原始文章:https ://robkendal.co.uk/blog/2020-01-27-react-redux-components-apis-and-handler-utilities-part-two

import { createSlice } from '@reduxjs/toolkit';
import { LOGOUT_USER } from '../redux/actions';

class CrudReducerFactory {
  constructor(slice, state = null, initialState = {}) {
    state = state || slice;

    this.initialState = initialState;

    const reducerResult = createSlice({
      name: slice,
      initialState: initialState[state],
      reducers: this._generateReducers(),

      extraReducers: (builder) => {
        builder.addCase(LOGOUT_USER, (state, action) => {
          return { ...this.initialState };
        });
      },
    });

    this.reducer = reducerResult.reducer;
    this.actions = reducerResult.actions;
  }

  _generateReducers = () => {
    return {
      // Create One
      requestCreateOne: (state, action) => {
        state.isLoading = true;
      },
      requestCreateOneSuccess: (state, action) => {
        state.isLoading = false;
        state.one = action.payload;
      },
      requestCreateOneError: (state, action) => {
        state.isLoading = false;
      },
      
      // ...snip...
    };
  };
}

export default CrudReducerFactory;

这是这样实例化的:

const factory = new CrudReducerFactory('users', 'users', { foo: 'bah', one: null, isLoading: false } );
第一个参数是切片的名称,第二个是状态切片,第三个是初始状态。

然后您可以使用factory.reducerfactory.actions相应地使用。

于 2020-10-24T15:43:21.210 回答