# React子组件性能优化
Table of Contents
在 React 中,父组件的重新 render 会引发子组件的重新 render。
子组件的重新渲染
类组件
import React from 'react'
class Child extends React.Component { render() { console.log('child render') return <>This is Child Component</> }}
export default class App extends React.Component { state = { count: 0, } handleClick = () => { this.setState({ count: this.state.count + 1, }) } render() { return ( <> <div> <button onClick={this.handleClick}>click me</button> count: {this.state.count} </div> <Child /> </> ) }}函数组件
import React, { useState } from 'react'
function Child() { console.log('child render') return <>This is Child Component</>}
export default function App() { const [count, setCount] = useState(0) return ( <> <div> <button onClick={() => setCount(count + 1)}>click me</button> count: {count} </div> <Child /> </> )}在上面的类组件和函数组件中,我们点击按钮 click,会刷新 count 值,导致父组件刷新,而子组件没有做任何状态的变化,但是也一并重新渲染。
为了避免不必要的渲染更新,提高渲染效率,有三个主要的方式:
- shouldComponentUpdate
- PureComponent
- React.memo
类组件
React.PureComponent
class Child extends React.PureComponent { render() { console.log('child render') return <>This is Child Component</> }}React.PureComponent 会以浅层对比 props 和 state 的方式实现函数。如果赋值了组件相同的 props 和 state,PureComponent 则可以提高性能,不进行重复渲染。
PureComponent 中的 shouldComponentUpdate() 仅作对象的浅层比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的对比结果。
且 PureComponent 中将跳过所有子组件树的 props 更新,因此确保所有子组件也是 PureComponent。
shouldComponentUpdate
class Child extends React.Component { shouldComponentUpdate() { return false } render() { console.log('child render') return <>This is Child Component</> }}通过使用 shouldComponentUpdate(nextProps, nextState) 进行对比,通过最终返回的 boolean 值决定是否重新渲染。
此方法仅作为性能优化的方式而存在,可以将 this.props 与 nextProps 以及 this.state 与 nextState 进行比较,并返回 false 跳过更新。返回 false 并不会阻止在 state 更改时重新渲染。
不建议经常使用 shouldComponentUpdate
函数组件
React.memo
React.memo 是一个高阶组件,所以它的语法如下:
const MyComponent = React.memo(function MyComponent(props) { /* render using props */})const Child = React.memo(function Child() { console.log('child render') return <>This is Child Component</>})如果组件在相同的 props 的情况下渲染相同的结果,那么可以通过包装在 React.memo 中调用,以此通过记忆组件渲染结果来提高组件的性能。React.memo 仅检查 props 变更,如果实现中拥有 useState、useReducer或useContext 的 Hook,当 state 或 context 发生变化时,它仍会重新渲染。