我正在开展一个大中型的反应/减少项目,我正在努力寻找反应/减少的最佳实践。
例如,如果我有一个饼图组件,它将采用一个简单的数组作为道具:
[{
label: 'a',
value: 10
}, {
label: 'b',
value: 6
}, ...]
但我从API服务器获取的源数据可能是这样的:
{
a: {
value1: 15,
value2: 3,
value3: 7,
...
},
b: { ... }
}
现在我必须做一些计算才能得到结果数据(比如value1 -value2 + value3 ......也许是一些过滤器...),问题是,我应该把这个计算放在 reducer (我觉得它更像是一个 getter ,它将通过connect
作为道具传递到组件,如getCartProducts
in this example),或者容器组件(在这种情况下可能是 Dashboard )?
我认为这两种选择都有道理:
:我们可以保持组件清洁,并将所有逻辑放在同一个地方。
:因为它与UI相关,并且如果计算的数据不可重复使用(仅针对该饼图),我们可以将这种计算保留在相关组件中。
如果我选择减速机,则会出现另一个问题。我应该在商店中保存计算数据吗?或者只保存源数据,并在每次渲染组件时计算它? The old React doc表示你不应该在状态中保存计算数据,不确定redux是否为真。
答案 0 :(得分:5)
<强>一般强>
商店应包含尽可能少的状态。
通过reselect在mapStateToProps中计算得到的数据, 记住结果。计算将立即被调用;
<强>可是:强> 如果派生数据的形状与应用程序中使用的形状不同(或者您需要一些计算),那么 你可以在获取后立即计算。 (例如,它可能是规范化数据)
我认为你应该坚持收集而不是数组,因为通过密钥获取数据要简单得多。 如果您不打算编辑特定项目的值,可以在减速器中预先计算它们。
例如通过选择器计算:
使用了选择器组合,以避免在更新过滤器时重新计算:
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)
};
};
btw收集中的订单无法保证,因此除了收集之外,您可能应该从服务器数组键中接收。然后代码会有点不同......