【问题标题】:Why isn't my reducer updating my store?为什么我的减速器不更新我的商店?
【发布时间】:2017-05-09 15:43:57
【问题描述】:

我是 redux 的新手,我正在尝试创建一个单独的 redux 应用程序。我遇到的问题是我的减速器不会更新我的商店。如果我要改变减速器中的商店,那么我会看到我的变化。我知道这是不好的做法,所以我试图在不改变它的情况下更新它,但是当我查看控制台时。我看不到状态的变化。有人可以帮我弄清楚为什么减速器不更新商店吗?

这是我的行动:

store.subscribe(() => {
  console.log("store changed", store.getState());
});

这是我的减速器:

const fruitReducer = function(state={
  fruits: [
    {
      "itemName": "banana",
      "price": 1.00,
      "quantityRemaining": 10
    },
    {
      "itemName": "apple",
      "price": 2.00,
      "quantityRemaining": 5
    },
    {
      "itemName": "raspberry",
      "price": 5.00,
      "quantityRemaining": 2
    },
    {
      "itemName": "kiwi",
      "price": 3.00,
      "quantityRemaining": 15
    },
    {
      "itemName": "pineapple,
      "price": 7.00,
      "quantityRemaining": 1
    },
    {
      "itemName": "strawberries",
      "price": 2.00,
      "quantityRemaining": 3
    }
  ]
}, action){
  if(action.type === "DEDUCT"){
    return Object.assign({}, state, {
      fruits: state.fruits.map((fruit, index) => {
        action.payload.map((actionFruit) => {
          if(fruit.itemName === actionFruit.itemName){
            let newQuantity = fruit.quantityRemaining - actionFruit.quantityRemaining;
            return Object.assign({}, fruit, {
              quantityRemaining: newQuantity
            });
          }
        });
        return fruit;
      })
    });
  }
  else
    return state;
}

下面是我的调度员的一个例子(我创建了两个做同样的事情):

store.dispatch({type: "DEDUCT", payload: [
  {
    "itemName": "banana",
    "quantityRemaining": 1
  },
  {
    "itemName": "apple",
    "quantityRemaining": 1
  },
  {
    "itemName": "strawberries",
    "quantityRemaining": 1
  }
]});

【问题讨论】:

    标签: redux immutability


    【解决方案1】:

    我看到的一个问题是您实际上并没有返回action.fruits.map() 的结果。如果你不使用花括号,箭头函数允许你省略 return 关键字,但是一旦你添加了花括号,你就像平常一样开始了一个函数的主体,你可以明确地返回一些东西。

    另外,作为一种风格说明,我建议将该减速器的初始状态定义为一个单独的变量:

    const initialState = [ /* fruits here */];
    
    const fruitReducer = (state = initialState, action) => {
        // reducer logic here
    }
    

    看起来您的嵌套更新逻辑走上了正轨,但您可能还想通读 Redux 文档的 Structuring Reducers - Immutable Update Patterns 部分。

    【讨论】:

    • 那么我会在action.fruits.map() 的右大括号之前返回actionFruit 吗?我试过了,reducer 仍然没有更新状态。
    【解决方案2】:

    我发现这种情况可以通过您编写中间件的方式发生。例如,我以前有:

    const store = createStore(
      rootReducer,
      applyMiddleware(epicMiddleware),
      composeEnhancers(applyMiddleware(...middleware))
    )
    

    然而,似乎双重应用中间件让 redux 脾气暴躁,它不会从 rootReducer 捕获新的状态更新,只是从 epicMiddleware (这是一个从副作用触发动作/reducers 的花哨的东西)。

    将我的epicMiddleware 转移到我的applyMiddleware(...middleware) 电话中解决了这些问题。也就是说,更新到以下工作:

    const store = createStore(
      rootReducer,
      composeEnhancers(applyMiddleware(...middleware)) // epicMiddleware is now in the `middleware` array
    )
    

    这可能不是您的问题,但它是可能导致您描述的症状的一件事。

    【讨论】:

      猜你喜欢
      • 2019-03-28
      • 2019-10-22
      • 2016-02-28
      • 2018-05-06
      • 2019-12-28
      • 1970-01-01
      • 2019-09-17
      • 2017-02-26
      • 1970-01-01
      相关资源
      最近更新 更多