React之组件性能优化的几种方式

组件更新机制

三种组件更新的情况:

  • 调用 forceUpdate 方法强制更新
  • 调用 setState 方法更新数据
  • props 值发生变化时

问题:当组件进行嵌套时,更新了其中的某一个组件后,其他组件的更新方式?
在这里插入图片描述
当一个组件进行更新时,不但会更新自己,也会更新后代组件。但是不会更新父组件和兄弟组件

减轻 state

目标: 降低页面更新的频率 (只要state中数据发生改变,页面就会重载)

方式: 不用做渲染的数据,不要放在state中 (例如:定时器,直接挂在到this上即可)

class App extends React.Component {
    
    
    // state中只保存要渲染到页面上的数据
  state = {
    
    
    userInfo: {
    
    
      username: 'zs',
      roleName: '超级管理员'
    },
    goodsList: [
      {
    
     id: 1, goodsName: '键盘', goodsPrice: 399},
      {
    
     id: 2, goodsName: '鼠标', goodsPrice: 199},
      {
    
     id: 3, goodsName: '耳机', goodsPrice: 699},
    ]
  }

	// 不用渲染到页面上的数据就直接挂在到 this 上即可
	componentDidMount () {
    
    
    this.timerId = setInterval(() => {
    
    }, 800)
  }

	componentWillUnmout () {
    
    
    clearInterval(this.timerId)
  }
}

避免不必要的渲染

组件更新机制: 当一个组件进行更新时,不但会更新自己,也会更新后代组件。但是不会更新父组件和兄弟组件

存在的问题: 子组件没有变化,但是因为父组件发生了更新,所以子组件也要进行更新。这种更新是没有必要的,只会浪费系统性能

解决方案: 钩子函数 shouldComponentUpdate 用来判断组件是否需要更新

执行机制: 在执行 render 渲染页面前会先调用 shouldComponentUpdate 来判断是否需要进行渲染,如果返回值为true则进行渲染,反之则不渲染 (shouldComponentUpdate --> render)

class App extends React.Component {
    
    
    // 参数1: 下一次 props 的值
    // 参数2: 下一次 state 的值
    // 返回值: 返回true则更新,返回false则不更新
    shouldComponentUpdate(nextProps,nextState){
    
    
        return true/false
    }

	render () {
    
    ...}
}

state

在 shouldComponentUpdate 方法中可以使用两个数据

  • nextState: state更新后的值
  • this.state: 未更新之前的值
  • 判断更新后的值和跟新前的值是否发生变化即可
import React from 'react'
import ReactDOM from 'react-dom'

// 目标: state 控制更新
// 每次点击按钮更新num中的数字
// 核心思想: 判断更新前后state中的num值是否相同,相同则不更新组件,不相同则更新
class App extends React.Component {
    
    
  state = {
    
    
    count: 0
  }

  shouldComponentUpdate (nextProps, nextState) {
    
    
    console.log('nextState', nextState)
    console.log('this.state', this.state)
    // 判断更新后的state和更新前的state数据是否一致
    // 不一致返回true执行更新,一致返回false不更新
    return nextState.count !== this.state.count
  }

  updateApp = () => {
    
    
    this.setState({
    
    
      count: Math.floor(Math.random() * 3)
    })
  }

  render () {
    
    
    console.log('render')
    return (
      <div>
        <p>{
    
    this.state.count}</p>
        <button onClick={
    
    this.updateApp}>更新组件</button>
      </div>
    )
  }

  componentDidUpdate () {
    
    
    console.log('App-componentDidUpdate')
  }
}

ReactDOM.render(<App />, document.querySelector('#app'))

props

shouldComponentUpdate 方法中的另外两个数据

  • nextProps: props 更新后的值
  • this.props: props 未更新前的值
  • 判断两次props中的值,来决定是否要更新
  • 注意: 当子组件不渲染时,父组件也不要进行渲染
import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
    
    
  state = {
    
    
    count: 0
  }

  // 判断父组件是否需要更新
  shouldComponentUpdate (nextProps, nextState) {
    
    
    return nextState.count !== this.state.count
  }

  updateApp = () => {
    
    
    this.setState({
    
    
      count: Math.floor(Math.random() * 3)
    })
  }

  render () {
    
    
    return (
      <div>
        <Show num={
    
    this.state.count} />
        <button onClick={
    
    this.updateApp}>更新组件</button>
      </div>
    )
  }

  componentDidUpdate () {
    
    
    console.log('App-componentDidUpdate')
  }
}

class Show extends React.Component {
    
    
  // 判断子组件是否需要更新
  shouldComponentUpdate (nextProps) {
    
    
    console.log('nextProps', nextProps)
    console.log('this.props', this.props)

    return nextProps.num !== this.props.num
  }

  render () {
    
    
    return (
      <div>{
    
    this.props.num}</div>
    )
  }

  componentDidUpdate () {
    
    
    console.log('Show-componentDidUpdate')
  }
}

ReactDOM.render(<App />, document.querySelector('#app'))

纯组件

纯组件: React.PureComponet 与 React.Component 功能相似,也可以用来实现类组件

作用: 纯组件内部自动实现了 shouldComponentUpdate 钩子函数

原理: 纯组件内部会自动比对前后两次 props 和 state 的值来决定是否需要重新渲染

class App extends React.PureComponent  {
    
    
    render () {
    
    
        return (
        	<div>纯组件</div>
        )
    }
}

案例:使用纯组件完成随机数案例

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.PureComponent {
    
    
  state = {
    
    
    count: 0
  }

  updateApp = () => {
    
    
    this.setState({
    
    
      count: Math.floor(Math.random() * 3)
    })
  }

  render () {
    
    
    return (
      <div>
        <div>{
    
    this.state.count}</div>
        <div><button onClick={
    
    this.updateApp}>随机更新</button></div>
      </div>
    )
  }

  componentDidUpdate () {
    
    
    console.log('App-componentDidUpdate')
  }
}

ReactDOM.render(<App />, document.querySelector('#app'))

猜你喜欢

转载自blog.csdn.net/PILIpilipala/article/details/113337907