React Redux:reducer 是否应该包含任何逻辑 [英] React Redux: Should reducers contain any logic

查看:49
本文介绍了React Redux:reducer 是否应该包含任何逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有添加、更新和删除案例的购物车减速器功能.我在 redux 商店中也有一个产品数组.当有两个项目添加到产品数组时,我增加数量值而不是两个项目.我的主要问题是,reducers 是否应该包含任何逻辑,即确定产品数组是否已经包含确切的产品并只返回产品数量的更新,或者是否应该在检查现有产品的展示组件中处理这种行为并添加一个新的产品或更新数量?

I have a cart reducer function with add, update and delete cases. I also have a product array within the redux store. When there are two items added to the product array, instead of having two items, I increment the quantity value. My main question is, should the reducers include any logic i.e. determine if the products array already contains the exact product and just returns an update on quantity of product or should this behavior be handled within the presentational component checking for existing products and either adding a new product or updating the quantity?

function CartReducer (state = initialState, action) {
  switch (action.type) {
    case AddToCart:
      return {
        ...state,
        products: [...state.products, action.product],
        totalPrice: state.totalPrice += (action.price * action.quantity)
      }

    case RemoveItemCart:

      return {
        ...state,
        products: [
          ...state.products.slice(0, action.index),
          ...state.products.slice(action.index + 1)
        ]
      }

    case UpdateItemQuantity:
      return {
        ...state,
        products: state.products.map((product, index) => {
          if (index === action.index) {
            return Object.assign({}, product, {
              quantity: action.quantity
            })
          }
          return product
        })
      }

    default:
      return state
  }
}

推荐答案

Per 关于在 reducer 和 action creators 之间拆分逻辑的 Redux FAQ 条目:

对于在减速器或动作创建器中究竟应该使用哪些逻辑片段,没有一个明确的答案.一些开发人员更喜欢拥有胖"的动作创建者,瘦"的reducer只是简单地将数据放入一个动作中,然后盲目地将其合并到相应的状态中.其他人试图强调保持动作尽可能小,并在动作创建者中尽量减少 getState() 的使用.(就这个问题而言,其他异步方法,例如 saga 和 observables 属于动作创建者"类别.)

There's no single clear answer to exactly what pieces of logic should go in a reducer or an action creator. Some developers prefer to have "fat" action creators, with "thin" reducers that simply take the data in an action and blindly merge it into the corresponding state. Others try to emphasize keeping actions as small as possible, and minimize the usage of getState() in an action creator. (For purposes of this question, other async approaches such as sagas and observables fall in the "action creator" category.)

在你的减速器中加入更多的逻辑有一些潜在的好处.动作类型可能会更具语义和更有意义(例如USER_UPDATED"而不是SET_STATE").此外,reducer 中的逻辑越多,时间旅行调试将影响更多功能.

There are some potential benefits from putting more logic into your reducers. It's likely that the action types would be more semantic and more meaningful (such as "USER_UPDATED" instead of "SET_STATE"). In addition, having more logic in reducers means that more functionality will be affected by time travel debugging.

这个评论很好地总结了二分法:

This comment sums up the dichotomy nicely:

现在,问题是在action creator中放什么,在reducer中放什么,胖和瘦动作对象之间的选择.如果你把所有的逻辑都放在动作创建器中,你最终会得到基本上声明状态更新的胖动作对象.Reducers 变得纯粹,愚蠢,添加这个,删除那个,更新这些功能.它们将很容易组合.但是您的业务逻辑并不多.如果您在 reducer 中放置更多逻辑,您最终会得到漂亮、精简的 action 对象,大部分数据逻辑都在一个地方,但是您的 reducer 更难组合,因为您可能需要来自其他分支的信息.您最终会得到大型减速器或减速器,这些减速器会从州的更高级别获得额外的参数.

Now, the problem is what to put in the action creator and what in the reducer, the choice between fat and thin action objects. If you put all the logic in the action creator, you end up with fat action objects that basically declare the updates to the state. Reducers become pure, dumb, add-this, remove that, update these functions. They will be easy to compose. But not much of your business logic will be there. If you put more logic in the reducer, you end up with nice, thin action objects, most of your data logic in one place, but your reducers are harder to compose since you might need info from other branches. You end up with large reducers or reducers that take additional arguments from higher up in the state.

我还写了 我自己对厚而薄"的看法;减速器:

在动作创建器中放置更多逻辑与在减速器中放置更多逻辑之间存在有效的权衡.我最近看到的一个好处是,如果您在 reducer 中有更多逻辑,那么如果您进行时间旅行调试(这通常是一件好事),这意味着可以重新运行更多的东西.

There's valid tradeoffs with putting more logic in action creators vs putting more logic in reducers. One good point that I saw recently is that if you have more logic in reducers, that means more things that can be re-run if you are time-travel debugging (which would generally be a good thing).

我个人倾向于同时将逻辑放在两个地方.我写的动作创建器需要时间来确定是否应该调度一个动作,如果是,那么内容应该是什么.但是,我也经常编写相应的reducer来查看action的内容并在响应中执行一些复杂的状态更新.

I personally tend to put logic in both places at once. I write action creators that take time to determine if an action should be dispatched, and if so, what the contents should be. However, I also often write corresponding reducers that look at the contents of the action and perform some complex state updates in response.

更新

截至 2020 年,我们特别建议将尽可能多的逻辑放在减速器中:

As of 2020, we specifically recommend putting as much logic as possible in reducers:

在可能的情况下,尽量将计算新状态的逻辑放在适当的 reducer 中,而不是放在准备和分派动作的代码中(如点击处理程序).这有助于确保更多实际应用逻辑易于测试,更有效地利用时间旅行调试,并有助于避免可能导致突变和错误的常见错误.

Wherever possible, try to put as much of the logic for calculating a new state into the appropriate reducer, rather than in the code that prepares and dispatches the action (like a click handler). This helps ensure that more of the actual app logic is easily testable, enables more effective use of time-travel debugging, and helps avoid common mistakes that can lead to mutations and bugs.

在某些情况下,应首先计算部分或全部新状态(例如生成唯一 ID),但应将其保持在最低限度.

There are valid cases where some or all of the new state should be calculated first (such as generating a unique ID), but that should be kept to a minimum.

这篇关于React Redux:reducer 是否应该包含任何逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆