即使在使用 memo 和 useCallback 之后,React 组件也会重新渲染

React component re-rendering even after using memo and useCallback

整个列表在状态更改时重新呈现,而不是特定的选定列表项

https://codesandbox.io/s/lfgxe (参考控制台查看渲染的组件)

单击“添加到主数组”按钮时,数组(状态)必须更新,只有特定的列表项必须重新呈现。但是列表中的所有项目都会重新呈现。我尝试传递关键道具、备忘录、回调,但没有用。

我引用的链接:

  1. https://alexsidorenko.com/blog/react-list-rerender/

  2. https://dmitripavlutin.com/dont-overuse-react-usecallback/

App.js:


export default function App() {
  const [value5, setValue5] = useState([]);
  let a = [1, 2, 3, 4, 5, 6];
  console.log("===========Parent component called ======================");

  let buttonClick = useCallback((keyID) => {
    setValue5((c) => [...c, keyID]);
  }, []);
  console.log(value5);
  return (
    <div className="App">
      {a.map((i) => {
        return (
          <MapperComp buttonClick={buttonClick} keyID={i} key={i.toString()}>
            <h1>{i} from the app.js</h1>
            <h1>{i} from the app.js</h1>
          </MapperComp>
        );
      })}
    </div>
  );
}

MapperComp.js:

import React, { memo } from "react";

const MapperComp = memo(({ buttonClick, keyID, ...props }) => {
  console.log("component", keyID);

  return (
    <div>
      <div>
        <h1>{keyID}</h1>
        {props.children}
        <button
          onClick={() => {
            buttonClick(keyID);
          }}
        >
          Add to the main array
        </button>
      </div>
    </div>
  );
});

export default MapperComp;

您已将 useCallback 用于 buttonClick,不会重新定义函数。但是 setValues 将更新 values 状态并重新渲染整个组件。为了解决它,您应该将此列表包装在 useMemo 中,并在依赖项数组中添加 a

const list = useMemo(() => {
   return (
      a.map((i) => {
        return (
          <MapperComp buttonClick={buttonClick} keyID={i} key={i.toString()}>
            <h1>{i} from the app.js</h1>
            <h1>{i} from the app.js</h1>
          </MapperComp>
        );
      }
   );
}, [a])