React性能优化之PureComponent,memo,key等

首先看一个案例

import React, { Component } from 'react'
function Header()
{
  console.log('Header被调用')
  return <h2>我是Header</h2>
}
class Banner extends Component{
  render(){
    console.log('Banner render函数被调用')
    return <h3>我是Banner组件</h3>
  }
}

function ProductList(){
  console.log('ProductList被调用')
  return (
    <ul>
      <li>商品列表1</li>
      <li>商品列表2</li>
      <li>商品列表3</li>
      <li>商品列表4</li>
    </ul>
  )
}
class Main extends Component{
  render(){
    console.log('Main render函数被调用')
    return (
      <div>
        <Banner/>
        <ProductList/>
      </div>
    )
  }
}

function Footer(){
  console.log('Footer被调用')
  return <h2>我是Footer组件</h2>
}


export default class App extends Component {
  constructor(props){
    super(props)
    this.state ={
      counter:0
    }
  }
  render() {
    console.log('App render函数被调用')
    return (
      <div>
        <h2>当前计数:{this.state.counter}</h2>
        <button onClick={e=>this.increament(1)}>+1</button>
        <Header/>
        <Main/>
        <Footer/>
      </div>
    )
  }
  increament(count){
     this.setState({
       counter:this.state.counter+=count
     })
  }
}

当我点击加一的时候,我仅仅只想让this.state里面的counter改变,
但是所有组件都重新渲染了一遍

在这里插入图片描述
这样是特别消耗性能的,那么有什么办法可以解决呢?这个时候就用到了PureComponent,memo 了,那么它们两个是干嘛的呢?

首先介绍一下一个函数shouldComponentUpdate,这个函数是决定要不要进行组件更新,它里面默认的是return true

然后代码应该这样写

import React, { PureComponent,memo } from 'react'

const MemoHeader = memo(function Header()
{
  console.log('Header被调用')
  return <h2>我是Header</h2>
})

class Banner extends PureComponent{
  render(){
    console.log('Banner render函数被调用')
    return <h3>我是Banner组件</h3>
  }
}

function ProductList(){
  console.log('ProductList被调用')
  return (
    <ul>
      <li>商品列表1</li>
      <li>商品列表2</li>
      <li>商品列表3</li>
      <li>商品列表4</li>
    </ul>
  )
}
class Main extends PureComponent{
  render(){
    console.log('Main render函数被调用')
    return (
      <div>
        <Banner/>
        <ProductList/> 
      </div>
    )
  }
}

const MemoFooter = memo(function Footer(){
  console.log('Footer被调用')
  return <h2>我是Footer组件</h2>
})



export default class App extends PureComponent {
  constructor(props){
    super(props)
    this.state ={
      counter:0
    }
  }
  render() {
    console.log('App render函数被调用')
    return (
      <div>
        <h2>当前计数:{this.state.counter}</h2>
        <button onClick={e=>this.increament()}>+1</button>
        <MemoHeader/>
        <Main/>
        <MemoFooter/>
      </div>
    )
  }
  increament(){
     this.setState({
       counter:this.state.counter+1
     })
  }
}

解释一下

PureComponent会对state,props进行浅层比较,counter从0变成1,
shouldComponentUpdate这个函数就是return true,
Banner,Main没有依赖任何的state,props,所以return false
当return true的时候组件才会重新调用
PureComponent解决类组件,memo解决函数式组件

之后再进行改变counter的值的时候,它们都不会再重新加载了

在这里插入图片描述
再来说一下key值这个优化diff算法

还是看一个案例

import React, { Component } from 'react'

export default class App extends Component {
  constructor(props){
    super(props);
    this.state={
      movies:['星际穿越','金刚']
    }
  }
  render() {
    const {movies} = this.state
    return (
      <div>
        <ul>
        {
          movies.map((item,index)=>{
          return <li key={item}>{item}</li>
          })
        }
        </ul>
        <button onClick={e=>this.addmovie()}>添加电影</button>
      </div>
    )
  }
  addmovie(){
     this.setState({
       movies:['功夫',...this.state.movies]
     })
  }
}

方式一:在最后位置插入数据
这种情况,有无key意义并不大
方式二:在前面插入数据
这种情况,在没有key的情况下,所有的li都需要进行修改

当子元素(li)拥有key时,react使用key来匹配原有树上的子元素以及最新树上的子元素:
在下面这种场景下,绑定key的元素仅仅进行位移,不需要进行任何的修改

注意:
key应该是唯一的
key不要使用随机数(随机数在下一次render时,会重新生成一个数字)
使用index作为key,对性能是没有优化的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值