React中useEffect与useLayoutEffect的区别
useLayoutEffect的官方定义
其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。 可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。
尽可能使用标准的 useEffect 以避免阻塞视觉更新。
例子
下面使用例子简单的演示这两者的区别。
假设有个场景,一个div,当屏幕分辨率大于600px时宽度100%,当小于600px时宽度设置为200px。
- 正常使用
useEffect
实现:
import React, { CSSProperties } from 'react';
const blockStyles: CSSProperties = {
background: 'pink',
height: 200,
width: '100%',
transition: 'all 1s ease-in'
};
function App() {
const [mobileStyles, setMobileStyles] = React.useState<CSSProperties>({});
React.useEffect(() => {
const mobile = matchMedia('(max-width: 600px)');
if (mobile.matches) {
setMobileStyles({ width: 200 });
}
}, []);
return (
<div>
<div style={{ ...blockStyles, ...mobileStyles }} />
</div>
);
}
export default App;
当你这样做后你会发现,当你的屏幕宽度小于600px时,粉色的div会由100%宽慢慢的变成200px。因为transition: 'all 1s ease-in'
,
每次刷新,都会这样。
- 将
useEffect
替换成useLayoutEffect
,其它保持不变。
React.useLayoutEffect(() => {
const mobile = matchMedia('(max-width: 600px)');
if (mobile.matches) {
setMobileStyles({ width: 200 });
}
}, []);
使用useLayoutEffect后,刷新则完全不会出现这一动画变化过程,而是直接显示200px的粉色div!