每当我的标签组件父组件呈现时,我的子组件也会呈现。
我的制表符组件父组件是下面的
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>
);
}
我的标签组件代码
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"
三次。
当父状态改变时,组件道具不会改变,所以我认为我可以跳过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联系
下面的import语句
import MemoizedTab from "./tab";
导入默认导出-不是指定的导出。
MemoizedTab
组件导出为名为export的而导出为默认导出的则不被记忆。
这就是为什么没有必要重新渲染Tab
组件的原因。
将import语句更改为
import { MemoizedTab } from "./tab";
防止不必要的重新渲染Tab
组件。