Fork me on GitHub

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

Coding Poineer

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进行数据处理计算
使用useMemousecallback分别对变量回调函数进行一个包裹处理

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>
  );
}
posted @ 2021-07-28 16:52  365/24/60  阅读(91)  评论(0编辑  收藏  举报