useEffect
useEffect 用來執(zhí)行副作用操作,副作用可以理解為對環(huán)境做出影響的操作,比如數(shù)據(jù)獲取,設(shè)置訂閱以及手動更改 React 組件中的 DOM 都屬于副作用;
可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 這三個函數(shù)的組合。
在每次 render 完畢后根據(jù)依賴確定是否執(zhí)行。
useEffect(() => {
// deps 依賴發(fā)生改變后執(zhí)行
}, deps);
用途
作為 componentDidMount 使用
useEffect(() => {
console.log('我執(zhí)行了')
// 每次初始化組件時執(zhí)行一次,之后不會執(zhí)行
}, []);
作為 componentDidUpdate 使用
useEffect(() => {
console.log('n 變化了')
// 每次 n 發(fā)生改變都會執(zhí)行一次
}, [n]);
如果不傳入依賴
useEffect(() => {
console.log('我執(zhí)行了')
// 組件內(nèi)每個狀態(tài)改變都會執(zhí)行
});
作為 componentWillUnmount 使用
useEffect(() => {
return () => {
console.log('我執(zhí)行了')
// 每次組件將要卸載時執(zhí)行
}
},[]);
如果同時存在多個 useEffect,會按照出現(xiàn)的順序依次執(zhí)行
useLayoutEffect
會先于 useEffect 執(zhí)行,在 DOM 變更之后,瀏覽器繪制頁面之前執(zhí)行,所以會阻塞初始數(shù)據(jù)的渲染,不會產(chǎn)生視覺上的更新。
// div 內(nèi)部 n 初始值為 0,刷新后
// n => 0 => 1000
useEffect(() => {
document.querySelector('div').innerText = 1000
}, [n])
// n => 1000
useLayoutEffect(() => {
document.querySelector('div').innerText = 1000
}, [n])
執(zhí)行順序
App() => 執(zhí)行 => 產(chǎn)生 VDOM =>
DOM(div.innerText = 0; div.innerText = 1000) =>
(useLayoutEffect) => 改變樣式內(nèi)容(render 完畢) => (useEffect)
為了用戶體驗,不阻塞試圖更新,降低延遲,優(yōu)先使用 useEffect (優(yōu)先渲染)