• useEffect和useLayoutEffect的区别


    烤冷面加辣条的抖音 - 抖音 (douyin.com)

    一、看下面的代码,即使调换useLayoutEffect和useEffect的位置依旧是useLayoutEffect先输出。

    1. import { useState, useEffect, useLayoutEffect } from "react";
    2. const Index = () => {
    3. useLayoutEffect(() => {
    4. console.log("useLayoutEffect");
    5. }, []);
    6. useEffect(() => {
    7. console.log("useEffect");
    8. }, []);
    9. return (
    10. <>
    11. <div>hahahahhah</div>
    12. </>
    13. );
    14. };
    15. export default Index;

    从下面代码可以看出useLayoutEffect有绝对的优先级,先执行

    二、以下代码在点击刷新后,输出结果只和本身的顺序有关,全部是useLayoutEffect也是如此

    三、

    1. import { useState, useEffect, useLayoutEffect, useRef } from "react";
    2. const Index = () => {
    3. const [aaa, setAaa] = useState(0);
    4. const [ccc, setCcc] = useState(false);
    5. const bbb = useRef(0);
    6. const clickFunction = () => {
    7. setAaa(aaa + 1)
    8. // bbb.current = bbb.current + 1;
    9. // setCcc(!ccc);
    10. };
    11. useEffect(() => {
    12. console.log("useEffect, [aaa]");
    13. }, [aaa]);
    14. useEffect(() => {
    15. console.log("useEffect,[]");
    16. }, []);
    17. useEffect(() => {
    18. console.log("useEffect");
    19. });
    20. useLayoutEffect(() => {
    21. console.log("useLayoutEffect,[]");
    22. }, []);
    23. useLayoutEffect(() => {
    24. console.log("useLayoutEffect");
    25. });
    26. return (
    27. <>
    28. {ccc ?<div>有CCC</div> :<div>没哟ccc</div>}
    29. <div>hahahahhah</div>
    30. <button onClick={clickFunction}>32222222222222214</button>
    31. </>
    32. );
    33. };
    34. export default Index;

    点击后会输出:

    ???????????我们知道useEffect有依赖值的时,在依赖值发生变化时会执行useEffect,其他两个不知道怎么回事,应该是页面发生重新渲染了。就会有这两个的输出

    四、

    1. import { useState, useEffect, useLayoutEffect, useRef } from "react";
    2. const Index = () => {
    3. const [aaa, setAaa] = useState(0);
    4. const [ccc, setCcc] = useState(false);
    5. const bbb = useRef(0);
    6. const clickFunction = () => {
    7. // setAaa(aaa + 1)
    8. // bbb.current = bbb.current + 1;
    9. setCcc(!ccc);
    10. };
    11. useEffect(() => {
    12. console.log("useEffect, [aaa]");
    13. }, [aaa]);
    14. useEffect(() => {
    15. console.log("useEffect,[]");
    16. }, []);
    17. useEffect(() => {
    18. console.log("useEffect");
    19. });
    20. useLayoutEffect(() => {
    21. console.log("useLayoutEffect,[]");
    22. }, []);
    23. useLayoutEffect(() => {
    24. console.log("useLayoutEffect");
    25. });
    26. return (
    27. <>
    28. {ccc ?<div>有CCC</div> :<div>没哟ccc</div>}
    29. <div>hahahahhah</div>
    30. <button onClick={clickFunction}>32222222222222214</button>
    31. </>
    32. );
    33. };
    34. export default Index;

    点击后会输出:

    ???????????我们知道useEffect有依赖值的时,在依赖值发生变化时会执行useEffect,其他两个不知道怎么回事,应该是页面发生重新渲染了。就会有这两个的输出

    五、在看开源项目的时候发现useEffect的使用场景有如下大多数都有依赖值

    1、useEffect里如果造成内存泄露的化,会在return里清空

    2、会请求数据

    3、依赖值可以有多个,依赖值变化就会去执行相关函数

    1. useEffect(() => {
    2. // 全局使用国际化
    3. i18n.changeLanguage(language || getBrowserLang());
    4. setLanguage(language || getBrowserLang());
    5. setAntdLanguage();
    6. }, [language]);
    7. useEffect(() => {
    8. if (echartsRef?.current) {
    9. myChart.current = echarts.init(echartsRef.current as HTMLDivElement);
    10. }
    11. myChart?.current?.setOption(options);
    12. window.addEventListener("resize", echartsResize, false);
    13. return () => {
    14. window.removeEventListener("resize", echartsResize);
    15. myChart?.current?.dispose();
    16. };
    17. }, []);
    18. useEffect(() => {
    19. timer.current = setInterval(() => {
    20. setTime(moment().format("YYYY年MM月DD日 HH:mm:ss"));
    21. }, 1000);
    22. return () => {
    23. clearInterval(timer.current);
    24. };
    25. }, [time]);
    26. // 获取按钮权限列表
    27. const getAuthButtonsList = async () => {
    28. const { data } = await getAuthorButtons();
    29. setAuthButtons(data);
    30. };
    31. // 监听窗口大小变化
    32. const listeningWindow = () => {
    33. window.onresize = () => {
    34. return (() => {
    35. let screenWidth = document.body.clientWidth;
    36. if (!isCollapse && screenWidth < 1200) updateCollapse(true);
    37. if (!isCollapse && screenWidth > 1200) updateCollapse(false);
    38. })();
    39. };
    40. };
    41. useEffect(() => {
    42. listeningWindow();
    43. getAuthButtonsList();
    44. }, []);
    45. useEffect(() => {
    46. screenfull.on("change", () => {
    47. if (screenfull.isFullscreen) setFullScreen(true);
    48. else setFullScreen(false);
    49. return () => screenfull.off("change", () => {});
    50. });
    51. }, []);
    52. // 刷新页面菜单保持高亮
    53. useEffect(() => {
    54. setSelectedKeys([pathname]);
    55. isCollapse ? null : setOpenKeys(getOpenKeys(pathname));
    56. }, [pathname, isCollapse]);

    更多参考官网:使用 Effect 同步 – React 中文文档

    总结:

  • 相关阅读:
    太牛了,用Python实现服务部署自动化
    Debian 开机自动挂载磁盘
    论文浅尝 | 思维树:使用大语言模型反复思考解决问题
    CRUD-SQL
    JWT Token在线解析解码
    VMware中LINUX系统配置NAT ssh远程访问
    PushBackInputStream
    通讯录的实现(详解)
    ESP8266-Arduino编程实例-MMA7660加速计驱动
    NC16679 [NOIP2003]神经网络
  • 原文地址:https://blog.csdn.net/m0_47999208/article/details/134270901