我的redux商店有以下结构:
{ A: {item1, item2, item3},
.....
F : {item1, item2, item3},
a : {anotherItem1, anotherItem2}
.....
z : {anotherItem1, anotherItem2}
}
也就是说,它是平的,并且属性具有标准化结构。问题是我有大约8个不同的屏幕,其中许多屏幕要从这些属性中访问大量特定项目。这意味着我的很多mapStateToProps
函数都有冗余代码。
例如,假设Screen1定义mapStateToProps
如下
mapStateToProps(state){
aitem1 : stata.a.item1,
aFormatted : formatFunction(state.a.item2, state.a.item3)
bitem1: state.b.item1,
bFormatted : formatFunction(state.b.item2, state.b.item2)
...
}
现在假设Screen2还希望为其道具提供完全相同的状态以及其他一些属性。那么Screen2应该有这样的mapStateToProps函数
mapStateToProps(state){
aitem1 : stata.a.item1,
aFormatted : formatFunction(state.a.item2, state.a.item3)
bitem1: state.b.item1,
bFormatted : formatFunction(state.b.item2, state.b.item2)
...
other stuff
}
如果屏幕3和4也需要相同的东西,问题只会恶化。那我怎么能避免这个问题呢?
您可以编写一个单独的函数来选择状态的某个部分并在mapStateToProps
函数中调用它:
const getDataParts = state => ({
foo: state.foo,
bar: state.baz,
});
然后在mapStateToProps
使用它像:
const mapStateToProps = state => ({
...getDataParts(state),
otherProp: state.someOtherProp,
});
编辑:
请注意,mapStateToProps
可能会在每次状态变化时被调用。如果您的选择器进行任何计算,它将为组件创建新的道具,即使计算结果相同,也会重新渲染。为了防止你必须使用像reselect
提供的库那样的记忆选择器。
有关进一步说明和示例,请参阅例如Idiomatic Redux: Using Reselect Selectors for Encapsulation and Performance。