React如何通过缓存优化避免组件重复渲染
这里主要分析在函数式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>
);
}