我的Redux商店已经标准化,即它非常扁平,每个实体类型都有它自己的切片。
以下是我的Redux商店的简化示例:
drawings
1: {name:'D1', thumbnailId: 33}
2: {name:'D2', thumbnailId: 34}
thumbnails
33: {filePath: 'path to local file'}
34: {filePath: null (i.e. needs to be downloaded)}
在以下情况下显示各个缩略图需要重新渲染的图表的列表视图:
图纸切片发生了变化,即新的,删除或更新的图纸
发生任何引用缩略图的更改,即缩略图34最终被下载(下载由Redux-Saga处理为异步)
我当前的 mapStateToProps 显然存在缺陷,因为它会从Redux商店中做出过多的选择。这是在实际视图获取其新道具之前发生的,因此我无法通过shouldComponentUpdate
来控制它。
我的应用程序中有几个地方需要更好的解决方案。
这是我有缺陷的mapStateToProps(我使用Immutable.js):
(state, ownProps) => {
const drawings = selectProjectDrawings(state, ownProps.projectId).map(drawing => {
const thumbnailFileGuid = drawing.get('thumbnailFileGuid');
if (!thumbnailFileGuid) return drawing;
const filePath = selectFile(state, thumbnailFileGuid).get(THUMBNAIL_FILE_PATH_FIELD);
return filePath ? drawing.set('_thumbnailFilePath', filePath) : drawing;
});
return {
drawings: drawings
};
}
编辑:
我当前解决方案的一个非常糟糕的事情是,我通过使用 _thumbnailPath 扩充它们来创建新的绘图对象。这意味着我无法比较 shouldComponentUpdate 中的对象引用,因为引用始终会被更改。
能够比较对象引用是不改变对象的主要论据之一,但是我已经用我有缺陷的解决方案抛弃了这个机会。
答案 0 :(得分:0)
我建议将此逻辑放在选择器后面。 reselect是一个记忆选择器,这意味着它将对你进行深度比较,如果返回的对象和内部的所有属性保持不变(包括深树状结构),那么它将返回原始值对象
React然后会注意到这是同一个对象实例(不是新的)并且不会重新渲染。如果在选择器中重新创建绘图对象,则可以,因为您没有在任何持久状态下捕获它。
旁注:随着您的应用增长,您会发现所有连接的组件都会被mapStateTpProps
调用,即使它与它无关,因此使用记忆选择器确实有帮助这里。否则,componentShouldUpdate
会很快变得复杂。