【问题标题】:Avoiding re-render unchanged items避免重新渲染未更改的项目
【发布时间】:2021-08-26 13:03:28
【问题描述】:

我正在尝试使用 React.memo 来提高包含可更改项目的长列表的性能,但我遇到了奇怪的行为。

重现步骤:

1 - 进入沙盒here

2 - 在第一项上按添加

3 - 在第二个项目上按添加

import React, { useState } from "react";

const App = () => {
  const [list, setList] = useState([
    { id: 1, qtd: 0 },
    { id: 2, qtd: 0 },
    { id: 3, qtd: 0 },
    { id: 4, qtd: 0 }
  ]);

  const onAdd = (id, qtd) => {
    setList(
      list.map((item) => {
        if (item.id === id) {
          return { ...item, qtd };
        } else {
          return item;
        }
      })
    );
  };

  return (
    <ul>
      {list.map((item) => (
        <Item {...item} onChange={onAdd} />
      ))}
    </ul>
  );
};

const Item = React.memo(({ id, qtd, onChange }) => {
  console.log("Rendering -> " + id);

  return (
    <li>
      <span>{qtd}</span>
      <button onClick={() => onChange(id, qtd + 1)}>Add</button>
    </li>
  );
}, areEqual);

function areEqual(prev, next) {
  return prev.qtd === next.qtd;
}

export default App;

【问题讨论】:

  • 你有什么问题?
  • 您是否尝试将key 属性添加到项目中?

标签: reactjs performance react-memo


【解决方案1】:

我已经修改了您的添加功能。并为 item 或 li 元素添加了 key 属性,因为这有助于反应确定 DOM 中哪个元素发生了变化。

const onAdd = (id, qtd) => {
    const oldList = [...list];
    oldList.forEach((element) => {
      if (element.id === id) {
        element.qtd=qtd;
      }
    });
    setList(oldList);
  };

    <ul>
      {list.map((item) => (
        <Item key={item.id} {...item} onChange={onAdd} />
      ))}
    </ul>

【讨论】:

    【解决方案2】:

    用list的最新状态解决了

    const App = () => {
      const [list, setList] = useState([
        { id: 1, qtd: 0 },
        { id: 2, qtd: 0 },
        { id: 3, qtd: 0 },
        { id: 4, qtd: 0 }
      ]);
    
      const onAdd = (id, qtd) => {
        setList((l) =>
          l.map((item) => {
            if (item.id === id) {
              return { ...item, qtd };
            } else {
              return item;
            }
          })
        );
      };
    
      return (
        <ul>
          {list.map((item) => (
            <Item key={item.id} {...item} onChange={onAdd} />
          ))}
        </ul>
      );
    };
    

    还添加了 Ngọc Hy 所述的密钥

    https://codesandbox.io/s/flamboyant-grothendieck-z8uxf?file=/src/App.js

    【讨论】:

      猜你喜欢
      • 2022-11-13
      • 2016-12-06
      • 2018-12-16
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 2021-03-12
      • 2021-05-08
      • 2015-09-08
      相关资源
      最近更新 更多