javascript - reselect如何影响组件的渲染

标签 javascript reactjs ecmascript-6 redux reselect

我不太明白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)
  }
};

它根据某个值从某个列表中组合一个元素。每次状态发生变化时都会调用 Render,例如我的 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 次?这到底是怎么回事?

最佳答案

React-Redux 的connect 函数依赖于浅层相等比较。每次存储更新和组件的 mapState 函数运行时,连接的组件都会检查返回对象的内容是否发生了变化。如果 mapState 返回了不同的东西,那么包装的组件必须重新渲染。

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

查看新Redux FAQ section on Immutable Data有关不变性和比较如何与 Redux 和 React-Redux 一起工作的更多信息。

关于javascript - reselect如何影响组件的渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43102371/

相关文章:

javascript - 在显示 :none element with hack 上执行过渡效果

reactjs - 无法在 React Native 中设置我的背景图片?

javascript - 我在改变对象吗?

javascript - 使用 javascript 将字符串数组转换为字段名称

javascript - 我怎样才能创建变量,这样我就不必在以后的函数中重复自己

Javascript 属性紧凑

javascript - create-react-app - 获取本地 JSON(通过 AJAX)

javascript - Object.prototype.toString 和 toString 有什么区别?

javascript - 关于链接 es6 Promises、then() 和值消耗

javascript - 如何在用户点击广告时删除广告?为了保护多次点击同一个广告?