我有一个相当简单的要求,即在我的Javascript应用程序中呈现开始/结束日期表:
<table>
<tr>
<th>Start Date</th>
<th>End Date</th>
<th>Number of weeks</th>
</tr>
<tr>
<td>2 Jan 2017</td>
<td>9 Jan 2017</td>
<td>1</td>
</tr>
<!-- etc -->
</table>
我的原始数据如下所示:
[
{
Id: 8672,
StartDate: "2017-01-02",
Weeks: 1
}
// More rows
]
我的问题是,执行这些字段的计算和格式化的最佳方法是什么,以便保持关注点的分离而不会对性能产生负面影响?我考虑了很多方法:
在数据存储到数据存储之前对其进行转换
我可以使用reducer函数或引发“数据加载”操作的代码片段将原始数据映射到更接近UI Component所需格式和字段的内容。这样做的好处是可以简化UI组件,但它确实将数据和减速器与用户界面控件紧密联系在一起。
执行计算&amp; UI组件中的格式设置
我可以在用户UI组件中格式化和解析数据。这似乎是个坏主意,因为它将UI组件与数据格式紧密联系在一起。
在表格UI的mapStateToProps中执行转换
这似乎是一种很好的方法,但它会强制react-redux绑定在每次状态更改时重新呈现整个表,因为每次渲染都会导致dates
道具具有不同的身份
const datesRow = (date) => (
<tr>
<td>{date.StartDate}</td>
<td>{date.EndDate}</td>
<td>{date.NumberOfWeeks}</td>
</tr>
)
const datesTable = ({dates}) => (
<table>
<tr>
<th>Start Date</th>
<th>End Date</th>
<th>Number of weeks</th>
</tr>
{ dates.map(datesRow) }
</table>
);
const mapStateToProps = (state) => ({
dates: state.dates.map(x => transformDates(x))
});
const DatesTableContainer = connect(mapStateToProps)(datesTable);
制作行UI组件并在那里进行映射
这似乎维持了之前选项提供的UI和状态之间的松散耦合,但也允许UI的增量更新。容器上看起来很重。这是个好主意吗?
const datesRow = (date) => (
<tr>
<td>{date.StartDate}</td>
<td>{date.EndDate}</td>
<td>{date.NumberOfWeeks}</td>
</tr>
)
const mapStateToPropsForRow = (state, ownProps) => {
const dateItem = lookupDateById(ownProps.dateId);
return {
StartDate: formatDate(dateItem.StartDate),
EndDate: calculateAndFormatEndDate(dateItem.EndDate),
NumberOfWeeks: dateItem.NumberOfWeeks
}
};
const DatesRowContainer = connect(mapStateToPropsForRow)(datesRow);
const mapStateToPropsForRow = (state, ownProps) => {
const dateItem = lookupDateById(ownProps.dateId);
return {
StartDate: formatDate(dateItem.StartDate),
EndDate: calculateAndFormatEndDate(dateItem.EndDate),
NumberOfWeeks: dateItem.NumberOfWeeks
}
};
const datesTable = ({id}) => (
<table>
<tr>
<th>Start Date</th>
<th>End Date</th>
<th>Number of weeks</th>
</tr>
<DatesRowContainer dateId={id} />
</table>
);
const mapStateToPropsForTable = (state) => ({
dates: state.dates.map(x => {id: x.id})
});
const DatesTableContainer = connect(mapStateToPropsForTable)(datesTable);
答案 0 :(得分:1)
最好的方法可能是在你的减速机中重新映射它。在那里,它只需要完成一次,而不是在每个渲染上执行,如果你要在mapStateToProps
- 或render
- 函数中重新映射它。您的数据获取(或从任何来源加载数据)已经是&#34; 慢动作&#34;无论如何,所以如果在那里添加重新映射,就不会打扰用户。
在最后两个中的任何一个中,您可能会使应用程序断断续续,特别是如果您的数据集很大或重新映射都很昂贵。 然而,每次重新报复都是不合理的。
或者您可以使用reselect库,但我自己还没有使用它,所以我无法对此发表任何评论。