首页 > 解决方案 > 避免重新渲染未更改的项目

问题描述

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

重现步骤:

1 - 转到此处的沙箱

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;

标签: reactjsperformancereact-memo

解决方案


我已经修改了您的添加功能。并将 key 属性添加到 item 或 li 元素,因为这有助于反应确定 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>

推荐阅读