這裡主要分析在函式式react中的優化,類元件有生命週期函式定義較明確
React的核心特徵之一是單向資料流(props自上往下流)
這會導致一個問題:當父元件state更新後,其自身及其所有children
(不論是否接收props)都會進行更新,但向下傳遞的props部分並未發生改變,我們應當讓這部分children不用重新渲染
在類元件中可以使用 componentShouldUpdate 控制是否更新
為什麼可以通過資料變化判斷是否更改?(React函式式元件是純函式,不會修改props(包含資料、函式),只能被動地根據props渲染。只要props不變,其渲染結果是可預測的)
一個元件需要重新渲染,有如下3種情況:
該元件自己的狀態state改變
父元件重新渲染,導致子元件重新渲染,但是父元件傳遞的 props未改變
父元件重新渲染,導致子元件重新渲染,但是父元件傳遞的 props 改變
情況1必須重新渲染,情況2不必,情況3需要
//目錄結構
..App.js
....pages
......TestOne.js
......TestTwo.js
// TestOne元件
export const TestOne = (props)=>{
console.log('渲染testone')
return (
<div>
testOne
</div>
)
}
// TestTwo元件
export const TestTwo = (props)=>{
console.log('渲染testone');
return (
<div>
TestTwo
</div>
)
}
// index.js
export {TestOne} from './testOne'
export {TestTwo} from './TestTwo'
//APP.js
import {TestTwo , TestOne} from './pages/index'
const App = () => {
const [num , setNum] = useState(0)
console.log('渲染');
return (
<div className="App">
<TestOne></TestOne>
<TestTwo></TestTwo>
<div onClick={()=>{setNum(num+1)}}>資料展示:<span>{num}</span></div>
</div>
);
}
效能優化有2個方面:
1、減少不必要的渲染
2、減少不必要的計算量
針對第1項:
使用React.memo包裹暴露的子元件
// TestTwo.js
export const TestTwo = React.memo(Fn,[compareFn(oldV,newV)])
// React.memo預設只會作第一層的props是否相同,props引用本身
針對第2項:
子元件可能會基於props進行世俗據處理計算
使用useMemo
、usecallback
分別對變數
、回撥函式
進行一個包裹處理
import {useMemo , useCallback} from 'react'
const App = () => {
const [num , setNum] = useState(0)
console.log('渲染');
const Callback = useCallback(()=>{
return setNum
},[setNum])
const numMemo = useMemo(()=>{
return num
},[num])
return (
<div className="App">
<TestOne></TestOne>
<TestTwo></TestTwo>
<div onClick={()=>{setNum(num+1)}}>資料展示:<span>{num}</span></div>
</div>
);
}