重新选择如何影响组件的渲染

时间:2017-03-29 19:20:07

标签: javascript reactjs ecmascript-6 redux reselect

我真的不明白重新选择如何减少组件的渲染。这就是我没有重新选择的内容:

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次?这里有什么好消息?

1 个答案:

答案 0 :(得分:4)

React-Redux的connect函数依赖于浅等式比较。每次商店更新并且组件的mapState功能运行时,该连接的组件将检查返回的对象的内容是否发生了变化。如果mapState返回了不同的内容,则包装的组件必须重新呈现。

重新选择使用" memoization",这意味着它保存了最后一个输入和输出的副本,如果它连续两次看到相同的输入,它将返回最后一个输出而不是重新计算。因此,如果输入没有改变,基于重新选择的选择器函数将返回相同的对象引用,这意味着connect更可能看到没有任何不同和包装的组件不会重新渲染。

有关不变性和比较如何与Redux和React-Redux协同工作的详细信息,请参阅新的Redux FAQ section on Immutable Data