javascript - 为什么我的组件使用 React.memo 重新渲染

标签 javascript reactjs react-hooks

每次我的选项卡组件父组件重新呈现时,我的子组件也会重新呈现。

我的标签组件父级如下

import { useState } from "react";
import "./styles.scss";
import Tab from "./tab";

export default function App() {
  const [selectTab, setSelectTab] = useState("a");
  console.log("parent render");
  return (
    <div className="App">
      <div className="tab-list">
        <Tab tab={"a"} title={"First Title"} setSelectTab={setSelectTab} />
        <Tab tab={"b"} title={"Second Title"} setSelectTab={setSelectTab} />
        <Tab tab={"c"} title={"Third Title"} setSelectTab={setSelectTab}
        />
      </div>
      {selectTab === "a" && <div>this is a</div>}
      {selectTab === "b" && <div>this is b</div>}
      {selectTab === "c" && <div>this is c</div>}
    </div>
  );
}

我的tab组件代码

const Tab = ({ title, tab, setSelectTab }) => {
  console.log("child render");
  const handleClick = (tab) => {
    setSelectTab(tab);
  }
  return <p onClick={() => handleClick(tab)}>{title}</p>;
};

export default Tab;

每次渲染我都会控制台记录 “parent render” 一次和 “child render” 三次。

只要父状态发生变化,组件 props 就不会改变,所以我想我可以使用 React.memo 跳过组件重新渲染并进行以下更改:

我的组件父级

import { useState } from "react";
import "./styles.scss";
import MemoizedTab from "./tab";

export default function App() {
  const [selectTab, setSelectTab] = useState("a");
  console.log("parent render");
  return (
    <div className="App">
      <div className="tab-list">
        <MemoizedTab
          tab={"a"}
          title={"First Title"}
          setSelectTab={setSelectTab}
        />
        <MemoizedTab
          tab={"b"}
          title={"Second Title"}
          setSelectTab={setSelectTab}
        />
        <MemoizedTab
          tab={"c"}
          title={"Third Title"}
          setSelectTab={setSelectTab}
        />
      </div>
      {selectTab === "a" && <div>this is a</div>}
      {selectTab === "b" && <div>this is b</div>}
      {selectTab === "c" && <div>this is c</div>}
    </div>
  );
}

我的内存标签组件代码

import React, { useCallback } from "react";

const Tab = ({ title, tab, setSelectTab }) => {
  console.log("child render");
  const handleClick = useCallback(
    (tab) => {
      setSelectTab(tab);
    },
    [setSelectTab]
  );
  return <p onClick={() => handleClick(tab)}>{title}</p>;
};

export default Tab;
export const MemoizedTab = React.memo(Tab);

但我控制台日志的方式与我的非内存代码相同。是什么导致选项卡组件重新呈现以及如何停止不必要的重新呈现?

我怀疑它可能是来自父级的 setSelectTab 函数,它是每次重新渲染时的新函数,导致组件重新渲染,尽管有 useCallback

Codesandbox link

最佳答案

下面的导入语句

import MemoizedTab from "./tab";

导入默认导出 - 而不是命名导出。

Memoized Tab 组件导出为命名导出,而导出为默认导出的组件未被内存。

这就是为什么不需要重新渲染 Tab 组件的原因。

将导入语句改为

import { MemoizedTab } from "./tab";

防止不必要地重新渲染 Tab 组件。

关于javascript - 为什么我的组件使用 React.memo 重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68887854/

相关文章:

javascript - 从 contenteditable 填充并保存文本

javascript - 如何在 python 中使用 selenium 获取包含在 HTML 标记中的 html 文档

javascript - 如何根据兄弟组件设置的 URL 重新加载 React 组件?

javascript - 如何在孙子组件中设置或更新数组的状态

javascript - IE9上加载图片后的事件

javascript - Ioniq 5 - 设置今天是星期一

javascript - ReactJS 和 Vivus SVG 动画

javascript - 在我的例子中,如何只使用一次 react hook useEffect?

javascript - 在 useEffect 内部或外部定义函数?

reactjs - 在 AgGridColumn onCellClicked 函数中 react Hook useState