![](https://img-blog.csdnimg.cn/859222a22ee5479db3660833ef8dfd01.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5YmN56uvZeermQ==,size_20,color_FFFFFF,t_70,g_se,x_16)
组件hook挂载时,先执行子组件 useEffect,再执行父组件 useEffect;
组件卸载时,分两种情况:
场景一:发生组件的卸载时,先执行父组件 hook,再执行子组件 hook;
// 装载过程是这样的的
// 子组件事件装载 => 子组件装载 => 父组件装载
// 卸载过程是这样的
// 子组件卸载 => 子组件事件卸载 => 父组件卸载
// 父组件
export default () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("父组件装载");
return () => {
console.log("父组件卸载");
};
});
return (
<div>
<p>{count}</p>
<Button
onClick={() => {
setCount(() => {
return count + 1;
});
}}
>
+
</Button>
{count >= 2 && count <= 3 ? <Child2 count={count} /> : <span>占坑</span>}
</div>
);
};
// 子组件
const Child2: FC<IProps> = (props) => {
useEffect(() => {
console.log("子组件装载");
return () => {
console.log("子组件卸载");
};
});
return (
<div>
Child2: {props.count}
<Button />
</div>
);
};
// 子组件中 Button
const Button = () => {
useEffect(() => {
console.log("子组件事件装载");
return () => {
console.log("子组件事件卸载");
};
});
return <div>Button</div>;
};
场景二:只发生渲染时,先执行子组件 hook,再执行父组件 hook;
// 装载过程是这样的的
// 子组件事件装载 => 子组件装载 => 父组件装载
// 卸载过程是这样的
// 子组件事件卸载 => 子组件卸载 => 父组件卸载
// 父组件
export default () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("父组件装载");
return () => {
console.log("父组件卸载");
};
});
return (
<div>
<p>{count}</p>
<Button
onClick={() => {
setCount(() => {
return count + 1;
});
}}
>
+
</Button>
<Child count={count} />
</div>
);
};
// 子组件
const Child: FC<IProps> = (props) => {
useEffect(() => {
console.log("子组件装载");
return () => {
console.log("子组件卸载");
};
});
return (
<div>
Child: {props.count}
<Button />
</div>
);
};
// 子组件 Button
const Button = () => {
useEffect(() => {
console.log("子组件事件装载");
return () => {
console.log("子组钮事件卸载");
};
});
return <div>Button</div>;
};
总的来说,组件会先标记要卸载的组件,先执行要卸载的组件 hook(unmount),再执行仅渲染的组件 hook (unmount)。