useLayoutEffect
的描述Reactjs文档里这样描述useLayoutEffect
:html
The signature is identical to
useEffect
, but it fires synchronously after all DOM mutations
only differs in when it is fired
即useLayoutEffect
跟useEffect
函数签名一致,可是在DOM修改后同步触发,这是和useEffect
惟一的区别。react
useLayoutEffect
?假设有个展现随机数字的case,当count
为0时随机生成个数字:git
useEffect
实现:import { useState, useEffect, useLayoutEffect } from 'react' export default function App() { const [count, setCount] = useState(0); useEffect(() => { console.log(`useEffect - count=${count}`) // 耗时的操做 const pre = Date.now(); while(Date.now() - pre < 500) {} // count为0时从新生成个随机数 if (count === 0) { setCount(10 + Math.random() * 200); } }, [count]); // 点击DIV重置count return ( <div onClick={() => setCount(0)}>{count}</div> ); }
能够看到展现0的过程。github
useLayoutEffect
实现:import { useState, useEffect, useLayoutEffect } from 'react' export default function App() { const [count, setCount] = useState(0); useLayoutEffect(() => { console.log(`useLayoutEffect - count=${count}`) // 耗时的操做 const pre = Date.now(); while(Date.now() - pre < 500) {} if (count === 0) { setCount(10 + Math.random() * 200); } }, [count]); return ( <div onClick={() => setCount(0)}>{count}</div> ); }
没有闪烁,当点击 div,count 更新为 0,此时页面并不会渲染,而是等待useLayoutEffect
内部状态修改后,才会去更新页面,因此页面不会闪烁。浏览器
Updates scheduled inside
useLayoutEffect
will be flushed synchronously, before the browser has a chance to paint
useLayoutEffect
会阻塞浏览器渲染,正好本例中useLayoutEffect
的实参函数里有个耗时操做,因此页面更新比较卡顿。useLayoutEffect
和componentDidMount
、componentDidUpdate
触发时机一致上面的例子改用class
组件实现试试:dom
import React from 'react' export default class App extends React.Component { constructor(props) { super(props); this.state = { count: 0 } } componentDidUpdate() { // 耗时的操做 const pre = Date.now(); while(Date.now() - pre < 500) {} } increaseCount = () => { this.setState(({ count }) => { return { count: count + 1} }) } render() { const { count } = this.state; return ( <div onClick={this.increaseCount}>{count}</div> ) } }
跟useLayoutEffect
效果同样:也是看不到闪烁,但也比较卡顿。ide
useLayoutEffect
和componentDidMount
和componentDidUpdate
触发时机一致(都在在DOM修改后且浏览器渲染以前);useLayoutEffect
要比useEffect
更早的触发执行;useLayoutEffect
会阻塞浏览器渲染,切记执行同步的耗时操做。除非要修改DOM而且不让用户看到修改DOM的过程,才考虑使用useLayoutEffect
,不然应当使用useEffect
。函数
注意:若是只是为了获取DOM属性(或其它get操做),则不必使用useLayoutEffect
,应当使用useEffect
。this
整理自gitHub笔记useEffect
和useLayoutEffect
到底有什么区别?spa