阅读 26

React 的生命周期

什么是生命周期?生命周期就是一个对象的生老病死。

Vue也有自己的生命周期,从Vue实例的创建、初始化、更新、销毁,在这个过程中间总是伴随着各种各样的事情,这些事情我们我们统称为生命周期。

constructor

  • 初始化 props

  • 初始化 state,但此时不能调用 setState

  • 用来写 bind this

    constructor(props){
    	super(props);
        this.state = {
        	n: 0
        }
        this.onClick = this.onClick.bind(this)
    }
    
    一般不这样写
    
    onClick=()=>{}
    constructor(){/*其他代码*/}
    复制代码

在某些情况下可以省略

shouldComponentUpdate

  • 返回 true 表示不阻止 UI 更新
  • 返回 false 表示阻止 UI 更新
import React from "react";

class App extends React.Component{
  constructor(props){
    super(props);
    this.state={
      n:1
    }
  }
  Click=()=>{
    this.setState(state=>({n:state.n+1}))
    this.setState(state=>({n:state.n-1}))
  }
  shouldComponentUpdate(oldProps,newProps){
  	if(newProps.n===this.state.n){
    	return false
    }else{
    	return true
    }
  }
  render(){
    console.log("render执行了一次")
    return(
      <div>
        {this.state.n}
        <button onClick={this.Click}>+1-1</button>
      </div>
    )
  }
}
export default App
复制代码

shouldComponentUpdate() 可以替换为 React.PureComponent

import React from "react";

class App extends React.PureComponent{
  constructor(props){
    super(props);
    this.state={
      n:1
    }
  }
  Click=()=>{}
  render(){}
}
export default App
复制代码

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

render

展示视图,只能有一个根元素,有两个根元素要用 <React.Fragment></React.Fragment> 包起来,可以缩写为 <></>React.Fragment 只是用来站位的,在 HTML 结构中不会显示

render(){
    	return (
        	<>
        		<div>hi</div>
                <div>你好</div>
            </>
        )
    }
}
复制代码

render 里面可以使用 if..else..?: 表达式,但是不能用 for 循环,需要用数组 array.map 来循环

componentDidMount

  • 在元素插入页面后执行代码,这些代码依赖 DOM,比如想获取 div 高度,最好在这里写
  • 在该处发起加载数据的AJAX请求(官方推荐)
  • 首次渲染会执行此钩子
import React from "react";

class App extends React.Component{
  Click=()=>{}
  componentDidMount(){
  	const div = document.getElementById('xxx')
    const {width} = div.getBoundingClientRect()
  }
  render(){
    return(
      <div id="xxx">
        {this.state.width}
      </div>
    )
  }
}
export default App
复制代码

componentDidUpdate

  • 在视图更新后执行代码
  • 此处也可以发起 AJAX 请求,用于更新数据
  • 首次更新不会执行此钩子
  • 此处 setState 可能会引起无限循环,因此要放在 if
  • shouldComponentUpdate 返回 false,则不会触发此钩子
import React from "react";

class App extends React.Component{
constructor(){
    super();
    this.state={
      n:0
    }
  }
 add(){
    this.setState(state=>{
      return {n:state.n+1}
    })
  }
  componentDidUpdate(){
  	console.log('更新了')
  }
  render(){
    return(
      <div>
        {this.state.n}
        <button onClick={()=>this.add()}>+1</button>
      </div>
    )
  }
}
export default App
复制代码

componentWillUnmount

  • 组件将要被移出页面然后被销毁时执行代码
  • unmount 过的组件不会再次 mount
import React from "react";

class App extends React.Component{
  Click=()=>{}
  componentDidMount(){
  	const Timer = setTimeout(()=>{
    	console.log("挂载")
    },1000)
  }
  componentWillUnmount(){
  	clearTimeout(Timer)
  }
  render(){
    return(
      <div>
      </div>
    )
  }
}
export default App
复制代码

总之,如果你在 componentDidMount 进行了监听、创建Timer、AJAX请求等操作,就一定要在 componentWillUnmount 中取消监听、Timer、AJAX等

文章分类
前端
文章标签