使用方式
这两个函数的使用方式其实非常简单,他们都接受一个函数一个数组,只有在数组里面的值改变的情况下才会再次执行 effect。所以对于使用方式我就不过多介绍了,不清楚的可以先参考官网 。
差异
useEffect
是异步执行的,而useLayoutEffect
是同步执行的。useEffect
的执行时机是浏览器完成渲染之后,而useLayoutEffect
的执行时机是浏览器把内容真正渲染到界面之前,和componentDidMount
等价。
import React, { useEffect, useLayoutEffect, useState } from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
const [state, setState] = useState("hello world")
useEffect(() => {
let i = 0;
while(i <= 100000000) {
i++;
};
setState("world hello");
}, []);
// useLayoutEffect(() => {
// let i = 0;
// while(i <= 100000000) {
// i++;
// };
// setState("world hello");
// }, []);
return (
<>
<div>{state}</div>
</>
);
}
export default App;
它的效果
而换成 useLayoutEffect
之后闪烁现象就消失了
看到这里我相信你应该能理解他们的区别了,因为 useEffect
是渲染完之后异步执行的,所以会导致 hello world 先被渲染到了屏幕上,再变成 world hello,就会出现闪烁现象。而 useLayoutEffect
是渲染之前同步执行的,所以会等它执行完再渲染上去,就避免了闪烁现象。也就是说我们最好把操作 dom 的相关操作放到 useLayouteEffect
中去,避免导致闪烁。
总结
- 优先使用
useEffect
,因为它是异步执行的,不会阻塞渲染 - 会影响到渲染的操作尽量放到
useLayoutEffect
中去,避免出现闪烁问题 useLayoutEffect
和componentDidMount
是等价的,会同步调用,阻塞渲染- 在服务端渲染的时候使用会有一个 warning,因为它可能导致首屏实际内容和服务端渲染出来的内容不一致。