react18中的useEffect和useLayoutEffect的原理分析

useEffect 是 React 中用于处理副作用的函数。它可以在组件渲染后执行一些额外的操作,例如发送网络请求、更新 DOM 等。

useEffect 的基本语法如下:

js 复制代码
useEffect(() => {
  // 副作用代码
}, [依赖项]);

其中,第一个参数是一个回调函数,会在组件渲染后执行;第二个参数是一个数组,表示该副作用函数所依赖的变量或状态。如果第二个参数为空数组,则该副作用函数只会在组件第一次渲染时执行一次。如果第二个参数包含某个变量或状态,则该副作用函数会在该变量或状态发生变化时重新执行。

不带依赖项的 useEffect 示例:

  • 只要组件渲染时执行一次
js 复制代码
useEffect(() => {
  // 副作用代码
});

useEffect 依赖项为空数组的示例:

  • 初始化时执行一次
js 复制代码
useEffect(() => {
  // 副作用代码
}, []);

useEffect 依赖项有值时的示例:

  • a, b, c, d 任意一个值变化时执行
js 复制代码
useEffect(() => {
  // 副作用代码
}, [a, b, c, d]);

useEffect中,我们可以使用async/await语法来处理异步操作。例如:

js 复制代码
useEffect(async () => {
  const result = await fetch("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  const data = await result.json();
  console.log("🚀 ~ useEffect ~ data:", data);
  return () => {}; // 返回一个清理函数,否则就会报错
}, []);

因为useEffect要返回的函数是清理函数,当我们在 callback 前面加上 async,返回了一个 promise,这个时候就需要返回一个清理函数,否则会报错。

或者可以这样写

js 复制代码
const getData = async () => {
  const result = await fetch("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  const data = await result.json();
  console.log("🚀 ~ useEffect ~ data:", data);
  return data;
};
getData();

清除函数的副作用,比如在组件卸载时清除定时器,且在里面函数里面获取的状态是上次更新的状态,不是当前最新的值,所以需要使用 useRef 保存状态

js 复制代码
useEffect(async () => {
  const [count, setCount] = useState(0);
  return () => {
    console.log(count)
}, []);

useEffect 的原理

函数组件在渲染(或更新)期间,遇到 useEffect 操作,会基于 MountEffect 方法把 callback(和依赖项)加入到 effect 链表中!

在视图渲染完毕后,基于 UpdateEffect 方法,通知链表中的方法执行!

1、按照顺序执行期间,首先会检测依赖项的值是否有更新「有容器专门记录上一次依赖项的值」;有更新则把对应的 callback 执行,没有则继续处理下一项!!

2、遇到依赖项是空数组的,则只在第一次渲染完毕时,执行相应的 callback

3、遇到没有设置依赖项的,则每一次渲染完毕时都执行相应的 callback

useLayoutEffect 的原理

其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。

可以使用它来读取 DOM 布局并同步触发重渲染。

在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

尽可能使用标准的 useEffect 以避免阻塞视觉更新。

相关推荐
Channing Lewis1 小时前
如何实现网页不用刷新也能更新
前端
努力搬砖的程序媛儿2 小时前
uniapp广告飘窗
前端·javascript·uni-app
dfh00l2 小时前
firefox屏蔽debugger()
前端·firefox
张人玉2 小时前
小白误入(需要一定的vue基础 )使用node建立服务器——vue前端登录注册页面连接到数据库
服务器·前端·vue.js
大大。2 小时前
element el-table合并单元格
前端·javascript·vue.js
一纸忘忧2 小时前
Bun 1.2 版本重磅更新,带来全方位升级体验
前端·javascript·node.js
杨.某某3 小时前
若依 v-hasPermi 自定义指令失效场景
前端·javascript·vue.js
猫猫村晨总3 小时前
基于 Vue3 + Canvas + Web Worker 实现高性能图像黑白转换工具的设计与实现
前端·vue3·canvas
浪浪山小白兔3 小时前
HTML5 常用事件详解
前端·html·html5
Python大数据分析@3 小时前
通俗的讲,网络爬虫到底是什么?
前端·爬虫·网络爬虫