黑马程序员技术交流社区

标题: 【上海前端】React 生命周期 [打印本页]

作者: 叶夜葉    时间: 2019-9-6 10:01
标题: 【上海前端】React 生命周期
React 生命周期转载自:https://www.jianshu.com/p/2c85958371af
组件生命周期分为部分
组件创建阶段:组件生命周期函数一辈子只执行一次
组件运行阶段:根据组件 state 跟 props 的改变,有选择性的触发0次或者多次
组件销毁阶段:一辈子只执行一次设置组件初始化默认值
在 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>







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2