【问题标题】:React + Redux, where should my UI-related calculations go, container components, or reducers?React + Redux,我的 UI 相关计算应该去哪里,容器组件还是 reducer?
【发布时间】:2016-12-14 21:45:27
【问题描述】:

我正在从事一个中型到大型的 react/redux 项目,我正在尝试找出 react/redux 的最佳实践。

例如,如果我有一个 饼图 组件,它将采用一个简单的数组作为道具:

[{
  label: 'a',
  value: 10
}, {
  label: 'b',
  value: 6
}, ...]

但我从 API 服务器获取的源数据可能是这样的:

{
  a: {
    value1: 15,
    value2: 3,
    value3: 7,
    ...
  },
  b: { ... }
}

现在我必须做一些计算来得到结果数据(比如 value1 -value2 + value3...也许是一些过滤器...),问题是,我应该把这个计算放在 reducer(我觉得它更像是一个getter,它会通过connect作为一个prop传递给一个组件,比如getCartProductsin this example),或者一个容器组件(在这种情况下可能是仪表板)?

我认为这两个选项都有意义:

  • 在 reducer 中:我们可以保持组件干净,并将所有逻辑放在同一个位置。

  • 在容器中:因为它与 UI 相关,并且如果计算的数据不可重用(仅适用于那个饼图),我们可以将这种计算保留在相关组件中。

如果我选择减速器,那么另一个问题来了。我应该将计算的数据保存在商店中吗?或者只是保存源数据,并在每次渲染组件时计算它? The old React doc 说您不应该将计算数据保存在状态中,不确定是否适用于 redux。

【问题讨论】:

    标签: javascript reactjs redux react-redux


    【解决方案1】:

    通常:

    1. 存储应包含尽可能少的状态。

    2. 派生数据通过reselect在mapStateToProps中计算, 记住结果。将立即调用计算;

    但是: 如果派生数据的形状与应用程序中使用的形状不同(或者您需要一些计算),那么 您可以在获取后立即计算。 (例如它可能正在规范化数据)

    我认为你应该坚持集合而不是数组,因为按键获取数据要简单得多。 如果您不打算编辑特定项目的值,您可以在 reducer 中预先计算它们。

    例如通过选择器计算:

    使用了选择器组合,以避免在更新过滤器时重新计算:

    import map from 'lodash/map';
    import { createSelector } from 'reselect';
    
    const getFilterKeys=(state)=>state.filter; //['a','b','c']
    //(btw it's just example... filter may be in props);
    
    const getItems=(state)=>state.entities.items;
    
    
    const calculateValues = (item) => item.value1 - item.value2 + item.value3;
    
    export const getItemsForChart = createSelector(
      [getItems],
      (items)=> map(items,(item,key)=>({label:key, value:calculateValues(item)}))
    );
    
    export const getItemsForChartWithFilter = createSelector(
      [getItemsForChart, getFilterKeys],
      (items, filterKeys)=> items.filter(item=>filterKeys.some(key=>key==item.label))
    );
    

    .

    const mapStateToProps=(state)=>{
      return {
        chartData:getItemsForChartWithFilter(state)
      };
    };
    

    不保证集合中的顺序,因此除了集合之外,您可能还应该从服务器键数组接收。然后代码会有点不同...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多