我真的不明白重新选择如何减少组件的渲染。这就是我没有重新选择的内容:
const getListOfSomething = (state) => (
state.first.list[state.second.activeRecord]
);
const mapStateToProps = (state, ownProps) => {
console.log(state.first.list, state.second.activeRecord);
return {
...ownProps,
listOfSomething: getListOfSomething(state)
}
};
它根据某些值从某个列表中复合元素。每当状态中的任何内容发生变化时,都会调用渲染,例如我的console.log
输出:
{}, ""
{}, ""
{}, ""
{}, "1"
{"filled", "1"}
因为商店的不同部分正在发生一些事情。因此,组件被渲染5次,冗余2次。
然而,使用重新选择:
const getList = state => state.first.list;
const getActiveRecord = state => state.second.activeRecord;
const listOfSomething = (list, activeRecord) => {
console.log(list, activeRecord);
return list[activeRecord];
}
const getListOfSomething = createSelector(getList, getActiveRecord, listOfSomething);
const mapStateToProps = (state, ownProps) => {
console.log(state.first.list, state.second.activeRecord);
return {
...ownProps,
listOfSomething: getListOfSomething(state)
}
};
这里我的第一个选择器console.log
输出:
{}, ""
{}, "1"
{"filled", "1"}
第二个:
{}, ""
{}, ""
{}, ""
{}, "1"
{"filled", "1"}
组件正确呈现 - 3次!
为什么会这样?为什么组件只渲染了3次?这里有什么好消息?
答案 0 :(得分:4)
React-Redux的connect
函数依赖于浅等式比较。每次商店更新并且组件的mapState
功能运行时,该连接的组件将检查返回的对象的内容是否发生了变化。如果mapState
返回了不同的内容,则包装的组件必须重新呈现。
重新选择使用" memoization",这意味着它保存了最后一个输入和输出的副本,如果它连续两次看到相同的输入,它将返回最后一个输出而不是重新计算。因此,如果输入没有改变,基于重新选择的选择器函数将返回相同的对象引用,这意味着connect
更可能看到没有任何不同和包装的组件不会重新渲染。
有关不变性和比较如何与Redux和React-Redux协同工作的详细信息,请参阅新的Redux FAQ section on Immutable Data。