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
经验文字内容,请参考苏南大叔的文字:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。