# useEffect
与 useLayoutEffect
的区别
useEffect
: 用来取代 componentDidMount
和 componentDidUpdate
. 主要作用是当页面渲染后, 进行一些副作用操作(比如访问 DOM
, 请求数据)
useLayoutEffect
: 作用与 useEffect
几乎一致.
观察以下两个例子:
useEffect
:
import { useEffect, useState } from 'react'
function App() {
const [msg, setMsg] = useState('hello world')
useEffect(() => {
let i = 0;
while(i <= 100000000) {
i++;
}
setMsg("world hello")
}, [])
return (
<div>{msg}</div>
)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
useLayoutEffect
:
import { useEffect, useState } from 'react'
function App() {
const [msg, setMsg] = useState('hello world')
useLayoutEffect(() => {
let i = 0;
while(i <= 100000000) {
i++;
}
setMsg("world hello")
}, [])
return (
<div>{msg}</div>
)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
可以看出, 使用 useEffect
在页面中进行 msg
的值, 页面会有细微的闪烁, 而 useLayoutEffect
则不会出现闪烁.
useEffect
在渲染完成后异步执行, 先将初始值hello world
渲染, 然后异步变成world hello
, 从而导致页面闪烁
useLayoutEffect
是渲染之前同步完成, 等到执行完成后再进行渲染.
# 总结
优先使用
useEffect
, 因为异步执行不会阻塞渲染影响渲染的操作统一放到
useLayoutEffect
, 避免页面闪烁useLayoutEffect
与componentDidMount
等价, 同步调用从而阻塞渲染在
SSR
项目中使用useLayoutEffect
会出现 warning, 这是useLayoutEffect
只有CSR
时才能使用, 这可能导致SSR
渲染的内容与实际不符. 而解决办法就是useIsomorphicLayoutEffect
:Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-ssr for common fixes.
import { useEffect, useLayoutEffect } from 'react' const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect export default useIsomorphicLayoutEffect
1
2
3
4