A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 叶夜葉 中级黑马   /  2019-9-6 10:01  /  2041 人查看  /  0 人回复  /   2 人收藏 转载请遵从CC协议 禁止商业使用本文

React 生命周期转载自:https://www.jianshu.com/p/2c85958371af
组件生命周期分为部分
组件创建阶段:组件生命周期函数一辈子只执行一次
  • componentWillMount:组件将要被挂载,此时还没有开始渲染虚拟 DOM(现在已经更名为UNSAFE_componentWillMount,相对于 Vue 中的 created
  • render:第一次开始渲染真正的虚拟 DOM,当 render 执行完,内存中就有完整的虚拟 DOM 了
  • componentDidMount:组件完成挂载,此时,组件已经显示到页面上了,当这个方法执行完,组件就都进入了运行中的状态(相对于 Vue 中的mounted
组件运行阶段:根据组件 state 跟 props 的改变,有选择性的触发0次或者多次
  • componentWillReceiveProps:组件将要接收新属性,此时,只要这个方法被触发,就证明父组件为当前子组件传递了新的属性值(首次并不会触发函数)
  • shouldComponentUpdate:组件是否需要被更新,此时,组件尚未被更新,但是,state 和 props 肯定是最新的
  • componentWillUpdate:组件将要被更新,此时,尚未开始更新,内存中的虚拟 DOM 树还是旧的,页面上的 DOM 树也是旧的
  • componentDidUpdate:此时页面又被重新渲染了, state和虚拟 DOM和页面已经完成保持同步
  • render:此时,又要重新根据最新的 state 和 props 重新渲染一颗内存中的虚拟 DOM 树,当 render 调用完毕,内存中的旧 DOM 树,已经被新 DOM 树替换了,此时页面还是旧的
组件销毁阶段:一辈子只执行一次
  • componentWillUnmount:组件将要被卸载,此时组件还可以正常使用



    image


设置组件初始化默认值
在 React 中,使用静态的 defaultProps 属性来设置组件的默认值
static defaultProps = {}
类型校验
注意:如果需要为传递过来的属性做类型校验,在 v.15.*之后需要安装cnpm i prop-types,因为官方把类型校验模块在v.15.*之后单独抽离了出来
import ResctPropTypes from 'prop-types'
[JavaScript] 纯文本查看 复制代码
static propTypes = {
default: ResctPropTypes.number
}
例子:
[JavaScript] 纯文本查看 复制代码
// @/components/propType
import React from 'react'
import ResctPropTypes from 'prop-types'

export default class PropType extends React.Component {
  constructor(porps) {
    super(porps)
    this.state = {
      default: porps.default
    }
  }
  static defaultProps = {
    default: 2
  }
  // 类型校验
  static propTypes = {
    default: ResctPropTypes.number
  }
  fun = {
    click: () => {
      this.setState({
        default: this.state.default + 1
      })
    }
  }
  
  // 组件将要被挂载
  componentWillMount() {
    console.log('created')
  }
  // 第一次开始渲染真正的虚拟 DOM,当 render 执行完,内存中就有完整的虚拟 DOM 了
  render() {
    // 每当调用 render() 函数时,页面中的 DOM 还是旧的
    console.log(this.refs.div && this.refs.div.innerHTML) // 运行中是才会打印 this.refs.div.innerHTML

    return <div id="div" ref="div">
      <button id="btn" onClick={this.fun.click}>+1</button><br/>
      默认值是:{this.state.default}
      <hr/>
      <Son value={this.state.default}></Son>
    </div>
  }
  // 执行完 componentDidMount 组件就进入了运行中的状态
  componentDidMount() {
    console.log('mounted', this.fun)
  }

  // ------------------ 下面是运行中的生命周期 -----------
  // 组件是否需要被更新,此时,组件尚未被更新,但是,state 和 props 肯定是最新的,
  // 注意:在 shouldComponentUpdate 中要求返回一个布尔值,
  // 返回 false 不会触发下面的 shouldComponentUpdate 后面的生命周期,而是退回了运行中的状态
  // 但是组件组件 state 中的值已经是被修改的了
  
  shouldComponentUpdate(nextProps, nextState) {
    // 下面做一个示例,展示 shouldComponentUpdate 中 this.state 中的值是怎么样的
    // 示例是 偶数更新视图,基数不更新视图  0 2 4

    // 发现了 this.state.default 并不是最新,是上一次的旧数据,那么我们可以通过 shouldComponentUpdate 的形参来获取最新的值
    console.log("this.state.default:", this.state.default,"---","nextState:", nextState)
    // this.state.default: 0 --- nextState: {default: 1}

    // return this.state.default % 2 === 0 ?true:false
    // return nextState.default % 2 === 0 ?true:false
    return true
  }

  // 组件将要被更新,此时,尚未开始更新,内存中的虚拟 DOM 树还是旧的,页面上的 DOM 树也是旧的
  componentWillUpdate(nextProps, nextState) {
    // 经过打印,发现页面上的 DOM 节点 和 state 都是旧的,需要慎重操作,因为你可能操作的是旧的 DOM.
    // console.log(document.querySelector('#div').innerHTML,'---this.state:',this.state)
    // Vue 中的 $refs 跟 React 的 refs 差一个 $
    console.log(this.refs.div.innerHTML, '---this.state:', this.state, '----nextState:', nextState)
    // <button id="btn">+1</button><br>默认值是:0<hr><div><p>子组件</p>0</div> ---this.state: {default: 0} ----nextState: {default: 1}
  }

  // 组件完成了更新,虚拟 DOM 和 页面上的 DOM 和 state 都是最新的
  componentDidUpdate(prevProps, prevState) {  // 因为 props 跟 state 都是最新的了,componentDidUpdate 函数提供了 上一次的 props(prevProps) 和 上一次的 state(prevState)
    console.log('最新的数据:', this.refs.div.innerHTML, '---this.state:',this.state)
    // 最新的数据: <button id="btn">+1</button><br>默认值是:1<hr><div><p>子组件</p>1</div> ---this.state: {default: 1}
  }
}

// 子组件
class Son extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      
    }
  }
  render() {
    return <div>
      <p>子组件</p>
      {this.props.value}
    </div>
  }

  // 组件将要接收新属性,此时,只要这个方法被触发,就证明父组件为当前子组件传递了新的属性值(首次并不会触发函数)
  componentWillReceiveProps(nextProps) {
    // 发现 this.props 不是最新的,是上一次的值
    console.log("触发了 componentWillReceiveProps", '子组件的props值:',this.props.value, '--- nextProps:',nextProps.value)
    // 触发了 componentWillReceiveProps 子组件的props值: 0 --- nextProps: 1
  }
}

// 父组件
<PropType default={0}></PropType>


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马