React学习笔记(四)-- 生命周期

473 阅读3分钟

class 生命周期

常用以及必须掌握的声明周期

  1. constructor()     // 初始化state

  2. **shouldComponentUpdate()   // return true 不阻止更新 / return false 阻止更新
    **

  3. render()  // 创建虚拟DOM

  4. ****componentDidMount ()      // 组件已经出现在页面上


  5. ******componentDidUpdate()     // 组件已经更新


  6. ********componentWillUnmount() // 组件即将销毁


简单的执行顺序

首次渲染 : constructor -- render -- 更新UI -- componentDidMount

再次渲染(更新数据):props/setState()改变了 -- shouldComponentUpdate -- 是否render ?

(Y) 更新UI  -- componentDidUpdate

(N) 结束

**销毁:**componentWillUnmount

* 1.constructor

用途:用来初始化props,state(但此时不能调用setState) 和 写bind this

class B extends React.Component{
  constructor(props){    
     super(props)
     this.state = {
       n:1,
       m:2
     }
     this.onClick = this.onClick.bind(this)
  }
}

* 2.shouldComponentUpdate / React.pureComponent

用途:返回 true不阻止UI更新 / false阻止UI更新

作用:可以手动设置判断是否要对组件进行更新,根据应用的场景灵活设置返回值,以避免不必要的更新

import React form 'react'
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(newProps,newState){   
     if(newState.n === this.state.n){    
        return false  
      }else{      
      return true    
    }   
 }   
 render(){  
      console.log('render 1次') 
       return(     
       <div>App    
          <div>     
         {{n}}   
           <button onClick={this.onClick}> + 1 </button>   
           </div>    
        </div>   
     )   
 }}

React 提供了内置功能 PureComponent ,可帮你直接判断state的值是否改变,如果没有改变则不执行

import React form 'react'
class App extends React.pureComponent { 
   constructor(props){  
      super(props)   
     this.state = {  
          n : 1    
    }   
 }  
  onClick = ()=>{   
     this.setState(state =>({     
       n: state.n + 1    
    }))     
   this.setState(state =>({   
         n: state.n - 1   
     }))  
  }

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

PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。
如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。

*3.render

用途:用于展示视图,只能有一个根元素。如果需要多个根元素需要使用<React.Fragment></React.Fragment>标签
可以使用 if...else 、 ?:表达式 ,不能直接使用for循环,因为for没有返回值,需要使用数组,建议使用array.map循环

import React form 'react'class App extends React.Component {   // ...          render(){      //单个元素        
      return(<div>App<div>)      // 多个元素
      return(
       <React.Fragment>
           <div>11</div>     
           <div>22</div>    
       </React.Fragment>
       // React.Fragment可简写为
       <>
           <div>11</div>     
           <div>22</div>    
       </>
       )

      // if...else 写法       if(...){
          return ( ... )
       }else{
          return ( ... )
       }
       
      // 循环写法 map
      return this.state.array.map(i => <div key={n}>{i}</div> )
      

   }}

*4.componentDidMount()

用途:在元素插入页面后执行代码,这些代码依赖DOM,比如如果想获取某个元素的高度、宽度,最好在这里写
此处可以发起加载数据的AJAX请求(官方推荐)
首次渲染会执行此钩子

import React form 'react'
class App extends React.Component {   
 constructor(props){    
   super(props)
   this.state = { 
     width:undefined
    }
 }
componentDidMount(){
 const app = document.getElementById('app')
 const {width} = app.getBoundingClientReact()
 this.setState({width})
}
 render(){
  <div id="app"> APP </div>
 }
}

可以使用React.createRef() 来获取元素,进行代码优化

这样写可以避免id声明冲突的问题

class App extends React.Component{
appRef = undefined  constructor(props){    
     super(props)
    this.state = {
      width:undefined
    }
     this.appRef = React.createRef()
  }
componentDidMount(){
 const app = this.divRef.current
 const {width} = app.getBoundingClientReact()
 this.setState({width})
}
 render(){
  <div ref={this.appRef}> APP </div>
 }}

*5.componentDidUpdate(prevProps,prevState,snapshot)

参数:prevProps更新前的props,prevState更新前的state

用途:在视图更新后执行代码。此处也可以发起AJAX请求,用于更新数据
在此处setState可能会引起无限循环,除非放在if里。

若shouldComponentUpdate返回false,则不触发此钩子,原因是数据进行更新会触发此钩子。

首次渲染不会执行此钩子(因为首次加载没有任何更新)

*6.componentWillUnmount

用途:组件将要被移出页面然后被销毁时执行代码,unmount过的组件不会再次mount
例如 :在componentDidMount中监听了 window scoll 或 计时器timer 或 AJAX请求,那么就应该在 componentWillUnmount 进行取消,因为组件已经销毁,监听没有意义