这是Pro React 16犹太洁食书中的Redux减速器示例吗?

时间:2019-05-02 21:48:10

标签: javascript reactjs redux

我正在学习React和Redux,目前正在阅读Adam Freeman的 Pro React 16 。考虑第5章中的减速器example。该减速器处理修改购物车的操作。这是减速器的一部分:

import { ActionTypes } from "./Types";

export const CartReducer = (storeData, action) => {
    let newStore = { cart: [], cartItems: 0, cartPrice: 0, ...storeData }
    switch(action.type) {
        case ActionTypes.CART_ADD: 
            const p = action.payload.product;
            const q = action.payload.quantity;

            let existing = newStore.cart.find(item => item.product.id === p.id);
            if (existing) {
                existing.quantity += q;
            } else {
                newStore.cart = [...newStore.cart, action.payload];
            }
            newStore.cartItems += q;
            newStore.cartPrice += p.price * q;            
            return newStore;

我的理解是,化简器必须是纯函数,但是当产品storeData中已经存在该变量时,似乎可以修改存储参数cart。具体来说,它将更新quantity购物车项目的existing属性,该属性来自storeData的{​​{1}}数组的浅表副本。因此,cart将被作为副作用进行修改。

我正确吗?

3 个答案:

答案 0 :(得分:2)

我认为你是对的。

不仅要改变状态(如您指出的那样),而且还要返回此变异的对象。

我相信您应该只使用Immutable JS中的'set'方法来更新化简器中的状态。

答案 1 :(得分:0)

这不是副作用。我将其称为用于新状态创建的元素的突变。

该减速器是纯的 不是纯,但是 IMHO足够好(当您知道优缺点时):

  • 从应用程序的角度来看,它可以完成工作
  • 为相同的输入返回相同的输出(可重复操作的顺序)

还原器角色是根据当前状态和操作创建新状态。 不再使用旧状态-此突变无关紧要。 没有任何要求/限制可以保持旧状态不变。

缺点:它会影响redux开发工具,撤消操作可能无法正常工作(仅在一个方向上重放操作-使用redux-undo进行真正的撤消)

PROS:简单性,较小的内存使用量

redux中有一个购物车示例-不同(更平坦)的数据结构。

答案 2 :(得分:0)

我认为创建减速器并返回新状态的正确方法如下:

export default CartReducer = (storeData = [], action) => {
    switch(action.type) {
       case ActionTypes.CART_ADD: 
           return [..state, { ..action.cart }]
       default:
           return storeData;
    }
}

通过这种方式,您可以创建state的新副本并简单地返回new state,还需要简化操作并避免做额外的事情,例如添加/更新购物车中的逻辑减速器代码。

您还需要创建一个default action并返回未修改的state