【问题标题】:Redux state update causing React component to render unnecessarilyRedux 状态更新导致 React 组件不必要地渲染
【发布时间】:2018-06-28 19:57:41
【问题描述】:

我在我的 react/redux 应用中遇到了一些性能问题。

我正在我的一个减速器中处理一个非常深的对象。它包含一个名为list 的对象,其中包含一个对象集合。

const state = {
  list: {
    one: {
      id: 'one',
      name: 'One',
      active: false
    },
    two: {
      id: 'two',
      name: 'Two',
      active: false
    }
  }
}

对象中的每个项目都用于渲染一个组件。该组件将访问项目的属性,如下所示:

const List = (props) => {
  const listItems = Object.keys(props.list).map((key) => {
    const item = props.list[key];
    return (
      <Item key={item.id} active={item.active}>
        {item.name}
      </Item>
    );
  });

  return <ul>{listItems}</ul>;
};

但是,每次我运行以下代码时,我的组件(它是一个 PureComponent)都会呈现。

case UPDATE_LIST_ITEM:
  return {
    ...state,
    list: {
      ...state.list,
      [payload.itemId]: {
        ...state.list[payload.itemId],
      },
    },
  };

Redux 文档提到“必须适当地复制和更新每一层嵌套”,然而,我什至没有更新任何值,而只是复制了对象。

我不确定这里可以做什么。现在是实现像 Immutable.js 这样的库的好时机吗?

更新:

另外(我不太确定这是否有帮助),以下 redux 更新不会导致我的组件呈现:

case UPDATE_LIST_ITEM:
  return {
    ...state,
    list: {
      ...state.list,
      [payload.itemId]: state.list[payload.itemId],
    },
  };

【问题讨论】:

  • 似乎每次你的reducer返回一个新状态时,它都会触发消耗整个对象的每个组件的重新渲染。也许我不理解你。你的对象是不是比上面那一两个人复杂得多?
  • 它还有一些属性,但仅此而已
  • 我相信这个问题是由对象指针改变引起的,因此导致了渲染。我想知道我是否应该执行检查以确保我应该返回一个新的/更新的状态副本,以及像 Immutable.js 这样的东西是否可以帮助解决这个问题
  • 您的mapState 函数是什么样的?您可能正在向PureComponent 提交正在更新的状态部分,所以是的,它将重新呈现。
  • 我不太清楚你的意思。我有一个部分,我在其中映射 Object.keys(props.list) 以呈现列表项(显示在我的问题中)

标签: reactjs redux immutability immutable.js


【解决方案1】:

您的纯组件正在使用状态中的props.list。在您的第一个 reducer 中,当您的代码到达该点时,您正在更新应用程序状态,并且如果您的组件从应用程序状态获取 list,那么如果 props 值发生更改,则重新渲染组件的预期行为。

如果您不希望组件在每次状态更改时重新渲染,您可以通过将组件升级到类并控制何时以及何时不渲染来控制它。 shouldComponentUpdate(nextProps, nextState)

React docs

【讨论】:

  • 我的列表项是一个类(因为它是一个 PureComponent)。我的理解是 PureComponents 实现了自己的浅 prop 和状态比较,所以没有理由使用 shouldComponentUpdate
  • react 文档还提到:“考虑使用内置的 PureComponent 而不是手动编写 shouldComponentUpdate()。PureComponent 对 props 和 state 进行浅比较,并减少您跳过的机会必要的更新。”
  • 您主要担心的是该组件不必要地重新渲染,对吗?我看到的情况基本上是这样的:case UPDATE_LIST_ITEM: 被调用并且状态发生变化。 mapStateToProps 更新 ` ` 导致你的纯组件重新渲染。也许您进行了不必要的调度,这导致了不需要的重新渲染?
猜你喜欢
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多