Redux 工具包中多个切片中的操作

Posted

技术标签:

【中文标题】Redux 工具包中多个切片中的操作【英文标题】:Actions in multiple slices in Redux toolkit 【发布时间】:2020-07-30 11:38:09 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

看起来这就是extraReducers 的用途:

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

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

【讨论】:

RTK 鼓励“按特征”切片。所以通常情况下,大多数动作在它们的核心中都有一个“自然”的特性,而其他减速器只是“顺其自然”。有时,一个动作并没有真正的“主要特征”,在这种情况下,只需使用 createAction 创建它并在多个切片(或普通减速器)中引用它就可以了。【参考方案2】:

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

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

参考

额外的减速器:https://redux-toolkit.js.org/api/createSlice#extrareducer

我用于工厂的原创文章: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 进行相应的使用。

【讨论】:

这段代码似乎与这个问题没有任何关系,尤其是像 this._generateReducers 这样的东西不见了,没有解释 stateslice 构造函数参数应该做什么。它并没有真正回答以任何方式提出的任何问题(因为这个问题更像是一个“理解某些东西”的问题)。这只是不完整的代码,没有解释。 为简洁起见,我故意不插入缺少的代码,但考虑到我错误地创建切片的上下文?假设它是不需要的。我试图更全面地解释我的答案,希望对您有所帮助。

以上是关于Redux 工具包中多个切片中的操作的主要内容,如果未能解决你的问题,请参考以下文章

对 redux 工具包的 createSlice 中的多个操作做出反应

使用 Redux 工具包的常见加载状态 reducer

从另一个存储切片中的一个存储切片调用一个 redux 操作

使用逗号运算符在 redux 工具包中的同一调度中调用多个减速器不起作用

react-redux 工具包应用程序在尝试将 redux 数据导入组件时出现问题

Redux 开发工具不适用于大型操作负载