React生命周期

1-1:生命周期阶段(v16之前)

  • 组件初始化阶段

    import React , (component) from 'react'
    class Text extends Component {
         constructor(props) {
       	 super(props);
      }
    }
    1:组件继承react component基类,从而拥有render,生命周期等方法。因为函数组件没有继承,所以函数组件没有生命周期等特性。
    2:super(props)用来调用基类的构造方法。也将父组件的props注入子组件,将组件读取(props只可读不可变,state可读可变)
    
  • 组件挂载阶段

    此阶段分为componentWillMount render componentDidMount 三个阶段

    • componentWillMount 在组建挂载前调用,而且只会被调用一次
    • render 函数只负责返回UI不负责渲染。返回的阶段依赖于它的参数。不能在里面执行this.setState()会有改变组件的副作用。
    • componentDidMount 组件挂载DOM后调用,只会被调用一次,
  • 组件更新阶段

    首先要明确react组件的更新机制,setState引起的state更新或者是父组件重新render引起的props更新,都会引起子组件的重新render,当进行性能优化时,我们可以通过shouldComponentUpdate 来阻止重新渲染。

    造成组件更新的情况

    • 父组件重新渲染render

      a:直接使用,当父组件重新render导致重传props,子组件将直接跟这个重新渲染,无论props是否变化。可以通过shouldComponentUpdate方法发优化

      class Child extends Component {
         shouldComponentUpdate(nextProps){ // 应该使用这个方法,否则无论props是否有变化都将会导致组件跟着重新渲染
              if(nextProps.someThings === this.props.someThings){
                return false
              }
          }
          render() {
              return <div>{this.props.someThings}</div
          }
      }
      

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

      class Child extends Component {
          constructor(props) {
              super(props);
              this.state = {
                  someThings: props.someThings
              };
          }
          componentWillReceiveProps(nextProps) { // 父组件重传props时就会调用这个方法
              this.setState({someThings: nextProps.someThings});
          }
          render() {
              return <div>{this.state.someThings}</div>
          }
      } 
      //在该函数(componentWillReceiveProps)中调用 this.setState() 将不会引起第二次渲染
      是因为componentWillReceiveProps中判断props是否变化了,若变化了,this.setState将引起state变化,从而引起render,此时就没必要再做第二次因重传props引起的render了,不然重复做一样的渲染了。
      
      
    • 组件本身调用setState,无论state有没有发生变化,可以通过shouldComponentData方法进行优化。

      class Child extends Component {
         constructor(props) {
              super(props);
              this.state = {
                someThings:1
              }
         }
         shouldComponentUpdate(nextStates){ // 应该使用这个方法,否则无论state是否有变化都将会导致组件重新渲染
              if(nextStates.someThings === this.state.someThings){
                return false
              }
          }
      
         handleClick = () => { // 虽然调用了setState ,但state并无变化
              const preSomeThings = this.state.someThings
               this.setState({
                  someThings: preSomeThings
               })
         }
      
          render() {
              return <div onClick = {this.handleClick}>{this.state.someThings}</div>
          }
      }
      

      此阶段分为componentWillReceiveProps shouldComponentUpdata,com componentWillUpdate

      render componentDidUpdate

      • componentWillReceiveProps(nextPorps) 此方法只调用与props引起的组件跟新过程中,相应props变化之后进行更新的唯一方式,参数nextProps时父组件传给当前组件的新props,但父组件render方法发调用不能保证重传给的当前组件的props是有变化的,所以在此方法中根据nextPorps何this.props来查明重传的props是否有变化,以及如果改变了执行啥,比如根据新this.setState触发当前组件重新render
      • shouldComponentUpdate(nextProps, nextState)

      此方法通过比较nextProps,nextState及当前组件的this.props,this.state,返回true时当前组件将继续执行更新过程,返回false则当前组件更新停止,以此可用来减少组件的不必要渲染,优化组件性能。

      ps:这边也可以看出,就算componentWillReceiveProps() 中执行了this.setState,更新了state,但在render前(如shouldComponentUpdate,componentWillUpdate),this.state依然指向更新前的state,不然nextState及当前组件的this.state的对比就一直是true了。

      如果shouldComponentUpdate 返回false,那就一定不用rerender(重新渲染 )这个组件了,组件的React elements(React 元素) 也不用去比对。 但是如果shouldComponentUpdate 返回true,会进行组件的React elements比对,如果相同,则不用rerende r这个组件,如果不同,会调用render函数进行rerender。

      img

      • componentWillUpdate(nextProps, nextState)

      此方法在调用render方法前执行,在这边可执行一些组件更新发生前的工作,一般较少用。

      • render

      render方法在上文讲过,这边只是重新调用。

      • componentDidUpdate(prevProps, prevState)

      此方法在组件更新后被调用,可以操作组件更新的DOM,prevProps和prevState这两个参数指的是组件更新前的props和state

  • 卸载阶段

此阶段只有一个生命周期方法:componentWillUnmount

此方法在组件被卸载前调用,可以在这里执行一些清理工作,比如清楚组件中使用的定时器,清楚componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏。

1-2:生命周期方法

getInitialState

初始化this.state的值,只在组件挂载阶段执行一次

getDefaultProps

只在租价你创建时调用一次并缓存返回对对象(在React.createClass之后就会调用)因为这个方法在实例初始化之前调用,所有在这个方法里面不能依赖this获取到这个组件的实例,在组件装载之后这个方法缓存的结果会用来保证访问this.props属性时,当这个组件没有在父组件中传入,也总是有值的

render

组装生成这个组件的 HTML 结构(使用原生 HTML 标签或者子组件),也可以返回 null 或者 false,这时候 ReactDOM.findDOMNode(this) 会返回 null

componentWillMount

只会在装载之前调用一次,在 render 之前调用,你可以在这个方法里面调用 setState 改变状态,并且不会导致额外调用一次 render

componentDidMount

在render之后,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。,从这里开始可以通过 ReactDOM.findDOMNode(this) 获取到组件的 DOM 节点。

componentWillReceiveProps(更新触发)

在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

shouldComponentUpdate(更新触发)

返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。可以在你确认不需要更新组件时使用。

componentWillUpdate(更新触发)

在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

componentDidUpdate(更新触发)

在组件完成更新后立即调用。在初始化时不会被调用。

componentWillUnmount(卸载触发)

在组件从 DOM 中移除之前立刻被调用。

posted @ 2020-11-02 15:21  Yanzq-X  阅读(50)  评论(0)    收藏  举报