我有时需要向组件发送静态道具,但数据实际上来自我的Redux商店。即我需要访问状态才能获取数据。
对于静态,我的意思是这个数据在组件的生命周期内不会改变,所以我不想在每个渲染的商店中选择它。
(state, ownProps) => ({
journalItemType: selectJournalItemType(state, ownProps.journalItemTypeId)
})
组件获取 JournalItemTypeId ,mapStateToProps在商店中查找它并将journalItemType发送到组件。 JournalItemType是静态元数据,不会经常更改,当然也不会在组件的生命周期内更改。
static propTypes = {
journalItemType: ImmutablePropTypes.map.isRequired,
}
这个问题是我在每次渲染时调用选择器。不是很大的表现,但无论如何都感觉不对。
(state, ownProps) => ({
getJournalItemType: () => selectJournalItemType(state, ownProps.journalItemTypeId)
})
我在组件构造函数中做的第一件事是调用getJournalItemType并将结果存储在本地状态。这样选择器只被调用一次。
static propTypes = {
getJournalItemType: PropTypes.func.isRequired,
}
constructor(props) {
super(props);
this.state = {
journalItemType: props.getJournalItemType()
}
}
这是正确的方法吗?
另一种方法是让组件了解状态,以便组件可以调用选择器本身。但我认为将国家排除在组件之外会更加清晰。
我也可以在调用链中调用选择器并获取静态数据,但我也没有状态。
如果是静态数据,为什么我会将 JournalItemTypes 存储在Redux存储中?所有应用程序元数据都在我的redux商店中,因此可以从服务器轻松刷新。通过将其保存在Redux中,我可以像处理同步传奇中的所有其他数据一样处理元数据。
我需要使用本地状态,因为组件是一个非常复杂的输入形式,具有各种输入(输入字段,相机,qr读取器,基于输入的实时更新SVG草图)。
我的应用中的JournalItem是“全有或全无”。即如果填写了每个必填字段,则允许用户保存该项目。我的商店坚持使用磁盘,所以我不想经常访问商店。所以JournalItem-object(实际上是一个Immutable.map)一直处于状态,直到它准备好被保存。
我的选择器通过重新选择进行记忆。这使我的第一个解决方案对性能的影响更小。但它仍然感觉不对。
由于其他事件,组件会通过props更新,因此它会不时重新渲染。
答案 0 :(得分:1)
这里有几个不同的选项:
这是最基本,最重要的' Redux'这样做的方式。如果您的selectJournalItemType
功能适度轻,则您的应用不会受到很大的性能影响,因为仅在商店更新according to react-redux docs时调用mapStateToProps
。
通常建议避免在Redux中使用Component的状态。有时它是必要的(例如有输入的表格)但在这种情况下它可以,并且在我看来应该避免。
如果您的功能在计算上非常昂贵,那么至少有几种方法可以优化原始解决方案。
在我看来,其中一个更简单的是optimizing the react-redux connect
。简短的例子:
const options = {
pure: true, // True by default
areStatesEqual: (prev, next) => {
// You could do some meaningful comparison between the prev and next states
return false;
}
};
export default ContainerComponent = connect(
mapStateToProps,
mapDispatchToProps,
mergeProps,
options
)(PresentationalComponent);
另一种可能性是创建memoized function using Reselect