一、看下面的代码,即使调换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 [ddd, setDdd] = 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,[dd]");
}, []);
useLayoutEffect(() => {
console.log("useLayoutEffect");
});
return (
<>
<button onClick={clickFunction}>32222222222222214</button>
</>
);
};
export default Index;
btn修改ccc的值
btn修改aaa的值
btn修改ddd的值
四、return不止在组件卸载后执行,也会在依赖值更新后执行,
import { useState, useEffect, useLayoutEffect, useRef } from "react";
const Index = () => {
const [aaa, setAaa] = useState(0);
const clickFunction = () => {
setAaa(aaa + 1)
};
useEffect(() => {
console.log("useEffect, [aaa]",aaa);
return () => {
console.log("useEffect, [aaa] return",aaa);
}
}, [aaa]);
return (
<>
<button onClick={clickFunction}>32222222222222214</button>
</>
);
};
export default Index;
点击按钮后会:执行return
五、在看开源项目的时候发现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 中文文档
总结: