react教程,如何用useLayoutEffect?与useEffect有何区别?
发布于 作者:苏南大叔 来源:程序如此灵动~
苏南大叔的react教程,本文说一下一个很鸡肋的函数useLayoutEffect。这个函数鸡肋到什么地步呢?连react官方都不建议你使用这个函数,都建议你使用useEffect来代替它。所以,你还想看这个useLayoutEffect函数是怎么回事么?useLayoutEffect和useEffect到底有什么区别呢?

苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。测试环境:create-react-app@5.0.1,react@18.2.0,react-dom@18.2.0,node@16.14.2。
不推荐使用useLayoutEffect
下面的文字是react官方原话:
注意 useLayoutEffect 与 componentDidMount、componentDidUpdate 的调用阶段是一样的。但是,我们推荐你一开始先用 useEffect,只有当它出问题的时候再尝试使用 useLayoutEffect。

使用方法和useEffect一致
使用方法和useEffect基本一致,连官方都推荐使用useEffect,而不是useLayoutEffect。两者都是以use开头,都是应用于函数组件的hook函数。参考文字:

挂载或更新:
useLayoutEffect(() => {
console.log("挂载或更新,useLayoutEffect");
});挂载和卸载[]:
useLayoutEffect(() => {
console.log("挂载,useLayoutEffect");
return () => {
console.log("卸载,useLayoutEffect");
}
}, []); 变量更新[var1,var2]:
useLayoutEffect(() => {
console.log("变量更新,useLayoutEffect");
},[state]);useLayoutEffect先于useEffect执行
执行顺序:useLayoutEffect => 浏览器渲染 => useEffect;

测试代码:
import React, { useEffect, useLayoutEffect, useState, useRef } from "react";
const Sunan = () => {
const [state, setState] = useState("sunan大叔");
useEffect(() => {
console.log("挂载");
return () => {
console.log("卸载");
}
}, []);
useEffect(() => {
console.log("挂载或更新");
});
useEffect(() => {
console.log("变量更新");
}, [state]);
useLayoutEffect(() => {
console.log("挂载,useLayoutEffect");
return () => {
console.log("卸载,useLayoutEffect");
}
}, []);
useLayoutEffect(() => {
console.log("挂载或更新,useLayoutEffect");
});
useLayoutEffect(() => {
console.log("变量更新,useLayoutEffect");
}, [state]);
return (
<div>
<button onClick={() => { setState("苏南大叔") }}>
{state}
</button>
</div>
);
};
export default Sunan;可见所有的useLayoutEffect输出都在useEffect输出之前。但是在这个例子中,并不能定义同为一组的"挂载"/"挂载或更新"/"变量更新"之间的前后顺序。

大家可以切换同一组中的代码的先后顺序,就会发现:对于同一组内的代码顺序,和代码定义的位置还是有关系的。

useLayoutEffect同步阻碍渲染,useEffect异步
useLayoutEffect和useEffect,效果上有所差异。差异点是:
useLayoutEffect是同步的,就是说在页面上出现dom元素之前,会等待useLayoutEffect的执行。也就是说,react处理的dom结构,在提交给浏览器渲染之前,会等待useLayoutEffect的再处理(也就是说会阻碍页面渲染)。useEffect是异步的,不会阻碍页面渲染,当浏览器已经渲染页面后,才会被执行。
例子如下:
import React, { useEffect, useState } from "react";
const Sunan = () => {
const [state, setState] = useState("sunan大叔");
useEffect(() => {
// console.log("挂载或更新");
let i = 0;
while (i <= 500000000) {
i++;
};
setState("------");
});
return (
<div>
<button onClick={() => { setState("苏南大叔") }}>
{state}
</button>
</div>
);
};
export default Sunan;
在这个例子中,证明是否阻碍页面渲染的证明是:使用useEffect的时候,可以明显看到state的数据变化。而useLayoutEffect则不会看到这个文字的变化过程,因为这个数据在提交给浏览器渲染之前就已经被修改过了。

import React, { useLayoutEffect, useState } from "react";
const Sunan = () => {
const [state, setState] = useState("sunan大叔");
useLayoutEffect(() => {
// console.log("挂载或更新");
let i = 0;
while (i <= 500000000) {
i++;
};
setState("------");
});
return (
<div>
<button onClick={() => { setState("苏南大叔") }}>
{state}
</button>
</div>
);
};
export default Sunan;结束语
更多react经验文字内容,请参考苏南大叔的文字: