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

use*_*999 1 javascript ecmascript-6 reactjs 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)
  }
};
Run Code Online (Sandbox Code Playgroud)

它根据某个值组合某个列表中的元素。每当状态发生任何变化时,都会调用Render,例如我的console.log输出:

{}, ""
{}, ""
{}, ""
{}, "1"
{"filled", "1"}
Run Code Online (Sandbox Code Playgroud)

因为商店的不同部分正在发生某些事情。因此,该组件被渲染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)
  }
};
Run Code Online (Sandbox Code Playgroud)

这是我的第一个选择器console.log输出:

{}, ""
{}, "1"
{"filled", "1"}
Run Code Online (Sandbox Code Playgroud)

第二:

{}, ""
{}, ""
{}, ""
{}, "1"
{"filled", "1"}
Run Code Online (Sandbox Code Playgroud)

组件渲染正确-3次!

为什么?为什么组件仅渲染3次?这到底是怎么回事?

mar*_*son 5

React-Redux的connect功能依赖于浅等式比较。每次商店更新并mapState运行组件的功能时,连接的组件都会检查返回的对象的内容是否已更改。如果mapState返回的内容不同,则包装后的组件必须重新渲染。

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

有关不可变性和比较如何与Redux和React-Redux一起工作的更多信息,请参见不可变数据上新的Redux FAQ部分