react 造成组件更新有两类(三种)情况

一. 父组件重新render

1.1直接使用,每当父组件重新render导致的重传props,子组件将直接跟着重新渲染,无论props是否有变化。可通过shouldComponentUpdate方法优化。

class写法:

import React, {Component} from 'react'
class Child extends Component {
  constructor(props) {
    super(props)
  }
  // 直接使用,每当父组件重新render导致的重传props,子组件将直接跟着重新渲染。
  // 无论props是否有变化。可通过shouldComponentUpdate方法优化。
  shouldComponentUpdate(nextProps) {
    if(nextProps.data === this.props.data) return false
    return true
  }
  render () {
    return (
      <div>
        <hr></hr>
        --- parent render ---
        <br />
        {console.log('child Render')}
        {this.props.data}
      </div>
    )
  }
}
export default Child

hook写法:

import React, {memo} from 'react'
const compare = (pre, cur) => {
  // 甚至可以更详细的过滤指定对象
  if(pre.data !== cur.data) return false
  return true
}
// 使用memmo代替shouldComponentUpdate
const Child = memo((props) => {
  return (
    <div>
      
      <hr></hr>
        --- parent render hook 使用memo缓存---
        <br />
      {console.log('childHook Render')}
      {props.data}
    </div>
  )
}, compare)

export default Child

1.2 在componentWillReceiveProps方法中,将props转换成自己的state

class写法:

import React, {Component} from 'react'
class Child extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: this.props.data
    }
  }
  // 父组件重传props时就会调用这个方法
  // 在该函数(componentWillReceiveProps)中调用 this.setState() 将不会引起第二次渲染。
  // 是因为componentWillReceiveProps中判断props是否变化了,若变化了,this.setState将引起state变化,从而引起render,
  // 此时就没必要再做第二次因重传props引起的render了,不然重复做一样的渲染了。
   componentWillReceiveProps(nextProps) {
    console.log('componentWillReceiveProps')
    console.log(nextProps.data)
    console.log(this.props.data)
    // 其实不做判断也不会再次执行,貌似该函数自身已经做了判断。
    if(nextProps.data != this.props.data) {
      this.setState({data: nextProps.data})
    }
  }
  render () {
    return (
      <div>
        <hr />
        --------propsToState componentWillReceiveProps组件提供props对比判断执行回调。---------
        <br />
        {console.log('propsToState Render')}
        <p>
          data: {this.state.data}
        </p>
      </div>
    )
  }
}
export default Child

hook写法:

import React, {useState, memo} from 'react'
const App = memo((props) => {
    const [data, setData] = useState(props.data)
    return (
      <div>
        <hr />
        --------propsToStateHook 使用memo---------
        <br />
        {console.log('propsToStateHook Render')}
        {data}
      </div>
    )
})
export default App

二,组件本身调用setState,无论state有没有变化。可通过shouldComponentUpdate方法优化。

class写法:

import React, {Component} from 'react'
class Child extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: 1
    }
  }
  // 应该使用这个方法,否则无论state是否有变化都将会导致组件重新渲染
  shouldComponentUpdate(nextProps, nextState) { 
    if(nextState.data === this.state.data) return false
    return true
  }
  render () {
    return (
      <div>
        <hr />
        --------self 设置对比---------
        <br />
        {console.log('selfSetState Render')}
        {this.state.data}
        <button onClick={() => this.setState({data: this.state.data})}>add</button>
        <button onClick={() => this.setState({data: this.state.data + 1})}>add+1</button>
        
      </div>
    )
  }
}
export default Child

hook写法:

import React, {useState} from 'react'
const Child = () => {
  const [data, setData] = useState(1)
  // 不改变data,没有组件重新渲染的问题。
  const handleClick = () => {
    setData(data)
  }
  return (
    <div>
      <hr />
        --------selfhook 默认data不变不会自更新---------
        <br />
      {console.log('selfSetStateHook Render')}
      {data}
      <button onClick={handleClick}>add</button>
      <button onClick={() => setData( data + 1)}>add + 1</button>
    </div>
  )
}
export default Child

注:

  • react版本:17

参考:React生命周期(包括react16版)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值