前言
- 在开发的时候往往
mounted
回调都只执行一次,因此下意识的觉得这是常识了 - 但其实
mounted
执行次数可以不是一次,取决于 React
在做 Diff
的时候是否卸载原结点
代码
- 该代码对
Inner
组件的相关生命周期进行研究 - 通过
toggle
按钮触发App
重绘
import { useEffect, useState } from "react";
const Inner = () => {
useEffect(() => {
console.log("Inner was mounted");
return () => {
console.log("Inner was unmounted");
};
}, []);
return <div>I'm Inner</div>;
};
export default function App() {
const [toggle, setToggle] = useState<boolean>(true);
return (
<div className="App">
<button
type="button"
onClick={() => {
setToggle((toggle) => !toggle);
}}
>
toggle
</button>
{toggle ? (
<div>
<Inner />
</div>
) : (
<span>
<Inner />
</span>
)}
</div>
);
}
效果截图
- 可以看到
Inner
组件的 mounted
跟 unmounted
回调在每一次切换都在执行

启发
- 在开发时,尽量不要切换
DOM
的父元素类型,否则会导致相关子树全部重新创建并挂载,且内部state
等状态全部被清空,既增加造成的性能消耗也不便状态管理