一、看下面的代码,即使调换useLayoutEffect和useEffect的位置依旧是useLayoutEffect先输出。
- import { useState, useEffect, useLayoutEffect } from "react";
- const Index = () => {
- useLayoutEffect(() => {
- console.log("useLayoutEffect");
- }, []);
- useEffect(() => {
- console.log("useEffect");
- }, []);
- return (
- <>
- <div>hahahahhah</div>
- </>
- );
- };
- export default Index;
从下面代码可以看出useLayoutEffect有绝对的优先级,先执行
二、以下代码在点击刷新后,输出结果只和本身的顺序有关,全部是useLayoutEffect也是如此
三、
- import { useState, useEffect, useLayoutEffect, useRef } from "react";
- const Index = () => {
- const [aaa, setAaa] = useState(0);
- const [ccc, setCcc] = useState(false);
- const bbb = useRef(0);
- const clickFunction = () => {
- setAaa(aaa + 1)
- // bbb.current = bbb.current + 1;
- // setCcc(!ccc);
- };
- useEffect(() => {
- console.log("useEffect, [aaa]");
- }, [aaa]);
- useEffect(() => {
- console.log("useEffect,[]");
- }, []);
- useEffect(() => {
- console.log("useEffect");
- });
- useLayoutEffect(() => {
- console.log("useLayoutEffect,[]");
- }, []);
- useLayoutEffect(() => {
- console.log("useLayoutEffect");
- });
- return (
- <>
- {ccc ?<div>有CCC</div> :<div>没哟ccc</div>}
- <div>hahahahhah</div>
- <button onClick={clickFunction}>32222222222222214</button>
- </>
- );
- };
- export default Index;
点击后会输出:
???????????我们知道useEffect有依赖值的时,在依赖值发生变化时会执行useEffect,其他两个不知道怎么回事,应该是页面发生重新渲染了。就会有这两个的输出
四、
- import { useState, useEffect, useLayoutEffect, useRef } from "react";
- const Index = () => {
- const [aaa, setAaa] = useState(0);
- const [ccc, setCcc] = useState(false);
- const bbb = useRef(0);
- const clickFunction = () => {
- // setAaa(aaa + 1)
- // bbb.current = bbb.current + 1;
- setCcc(!ccc);
- };
- useEffect(() => {
- console.log("useEffect, [aaa]");
- }, [aaa]);
- useEffect(() => {
- console.log("useEffect,[]");
- }, []);
- useEffect(() => {
- console.log("useEffect");
- });
- useLayoutEffect(() => {
- console.log("useLayoutEffect,[]");
- }, []);
- useLayoutEffect(() => {
- console.log("useLayoutEffect");
- });
- return (
- <>
- {ccc ?<div>有CCC</div> :<div>没哟ccc</div>}
- <div>hahahahhah</div>
- <button onClick={clickFunction}>32222222222222214</button>
- </>
- );
- };
- export default Index;
点击后会输出:
???????????我们知道useEffect有依赖值的时,在依赖值发生变化时会执行useEffect,其他两个不知道怎么回事,应该是页面发生重新渲染了。就会有这两个的输出
五、在看开源项目的时候发现useEffect的使用场景有如下大多数都有依赖值
1、useEffect里如果造成内存泄露的化,会在return里清空
2、会请求数据
3、依赖值可以有多个,依赖值变化就会去执行相关函数
- useEffect(() => {
- // 全局使用国际化
- i18n.changeLanguage(language || getBrowserLang());
- setLanguage(language || getBrowserLang());
- setAntdLanguage();
- }, [language]);
-
- useEffect(() => {
- if (echartsRef?.current) {
- myChart.current = echarts.init(echartsRef.current as HTMLDivElement);
- }
- myChart?.current?.setOption(options);
- window.addEventListener("resize", echartsResize, false);
- return () => {
- window.removeEventListener("resize", echartsResize);
- myChart?.current?.dispose();
- };
- }, []);
-
- useEffect(() => {
- timer.current = setInterval(() => {
- setTime(moment().format("YYYY年MM月DD日 HH:mm:ss"));
- }, 1000);
- return () => {
- clearInterval(timer.current);
- };
- }, [time]);
-
- // 获取按钮权限列表
- const getAuthButtonsList = async () => {
- const { data } = await getAuthorButtons();
- setAuthButtons(data);
- };
- // 监听窗口大小变化
- const listeningWindow = () => {
- window.onresize = () => {
- return (() => {
- let screenWidth = document.body.clientWidth;
- if (!isCollapse && screenWidth < 1200) updateCollapse(true);
- if (!isCollapse && screenWidth > 1200) updateCollapse(false);
- })();
- };
- };
- useEffect(() => {
- listeningWindow();
- getAuthButtonsList();
- }, []);
-
- useEffect(() => {
- screenfull.on("change", () => {
- if (screenfull.isFullscreen) setFullScreen(true);
- else setFullScreen(false);
- return () => screenfull.off("change", () => {});
- });
- }, []);
-
- // 刷新页面菜单保持高亮
- useEffect(() => {
- setSelectedKeys([pathname]);
- isCollapse ? null : setOpenKeys(getOpenKeys(pathname));
- }, [pathname, isCollapse]);
更多参考官网:使用 Effect 同步 – React 中文文档
总结: