1

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

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 次?这里到底发生了什么?

4

1 回答 1

5

React-Redux 的connect功能依赖于浅等式比较。每次存储更新并且组件的mapState函数运行时,该连接的组件都会检查返回对象的内容是否更改。如果mapState返回不同的东西,那么被包装的组件必须需要重新渲染。

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

有关不可变性和比较如何与 Redux 和 React-Redux 一起工作的更多信息,请参阅关于不可变数据的新Redux 常见问题解答部分。

于 2017-03-29T21:15:16.387 回答