React 生命周期

488 阅读3分钟

生命周期就相当于一个组件的一生,他有生(constructor),老(update),病(willUnmount),死等阶段,下面是几个重要的React生命周期

  1. constructor -初始化state和props阶段
  2. shouldComponenUpdate -boolean false则阻止更新
  3. render -创建虚拟DOM节点
  4. componentDidMount -组件出现在页面中
  5. componentDidUpdate -组件更新后
  6. componentWillUnmount -组件死亡前

(一)constructor

这个阶段是用来初始化props即,这是为了将外部的props绑定到self上,这样就可以通过this.props访问props中的数据,这时候并不能调用setState

class Son extends React.Component {
  constructor(props) {
  super(props)
  }

且这个过程会又一个绑定函数的this的过程

class Son extends React.Component {
  constructor(props) {
  super(props)
  this.onClick=this.onClick.bind(this)
  //在第二种写法中省略
  }
  onClick(){
      ...
  }
  //等价于
  onClick=()=>{
      ...这样就不需要bind
  }

当然如果你不需要初始化state则可以省略constructor,因为props是默认初始化并可直接在render中使用的

(二)shouldComponenUpdate

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state={
      n:1
    }
    }
  onClick=()=>{
    this.setState((state)=>({
      n:state.n+1
    }))
    this.setState((state)=>({
      n:state.n-1
    }))
  }
  shouldComponentUpdate(nextProps, nextState, nextContext) {
    if(nextState.n===this.state.n){
      return false
    }else{
      return true
    }
  }

  render() {
    console.log(1)
    return  (
      <div>App
        {this.state.n}
        <button onClick={this.onClick}>+1</button>
      </div>
    )
    }
}

他会自动传入3个参数,也就是新的props,state和context,你可以对新旧参数进行一个判断,如果参数相同则不执行render

比如例子中,onClick事件让n+1后n-1,n不变,虽然这时候的n的值没变,但是此时的n和之前的n已经不是同一个对象了,这是react的特色,这时候在此生命周期函数中进行判断,若n相同则返回false,render不执行

上述这个功能React已经想到了并提供了内置此功能的组件PureComponent,但是这个逻辑其实是一个浅比对,也就是只对比一层对象,且会同时对比props以及state对象是否发生了改变,任一改变就会render

class App extends React.PureComponent{
    ...
}

(三)render

1. render返回一个虚拟DOM节点的对象

在书写JSX的时候必须用一个div将内部标签包裹,如果不想在页面中多显示一个div则可以使用React.Fragment或者直接写一个空标签<></>

render(){
    <React.Fragment>
    ....
    </React.Fragment>
    //占位用,不渲染进页面
}

2. if

在React的JSX语法中你可以写js

render() {
    return  (
      <div>
        {this.state.n%2===0?<div>偶数</div>:<div>奇数</div>}
        <button onClick={this.onClick}>+1</button>
      </div>
    )
}

3. for

render() {
   return this.state.array.map(m=><div key={m}>{m}</div>)
  }

我们可以遍历一个数组,这里选择map,你也可以用for,但是for循环内部不能return,只能用一个数组来储存循环产生的节点然后最后return

同时要加上一个key来表征每一项的唯一性

(四) componentDidMount

在元素插入页面后执行的代码,这些代码依赖于DOM,比如获取元素的高度等,你也可以在这里发起加载数据的AJAX请求,且首次渲染必执行此钩子

(五)componentDidUpdate

  1. 视图更新后执行此代码
  2. 此钩子也可以发起AJAX请求,用于更新数据
  3. 首次渲染并不会执行此钩子
  4. 若在此钩子内setState则会死循环的,除非加了if
  5. 可以在shouldComponentUpdate中禁用此更新
componentDidUpdate(prevProps, prevState, snapshot)

他传入3个参数,之前的props和之前的state

(六) componentWillUnmount

这个钩子的含义是组件被销毁前,你可以在这里将事件监听取消,计时器取消等,防止不必要的代码占用内存

几个钩子的顺序

已被弃用的钩子