zoukankan      html  css  js  c++  java
  • React 生命周期

    React生命周期(生命周期钩子函数)

    一个关于生命周期的demo

    需求:定义组件实现以下功能:

    • 让指定的文本做显示 / 隐藏的渐变动画

    • 从完全可见,到彻底消失,耗时2S

    • 点击按钮从界面上卸载组件

    
    class Demo extends React.Component{
       state = {
           opacity:1
       }
       // 卸载组件
       handleComponent = () => { 
           ReactDOM.unmountComponentAtNode(document.getElementById('test'))
       } 
       // 组件挂载完毕
       componentDidMount(){
           this.timer = setInterval(()=>{
               let {opacity} = this.state;
               opacity -= 0.1
               if (opacity <= 0) opacity = 1 
               this.setState({
                   opacity:opacity
               })
           },200)
       } 
       // 组件将要卸载
       componentWillUnmount(){
           clearInterval(this.timer)
       } 
       // 初始化渲染组件,状态更新之后 
       render(){
           console.log("render")
           return (
               <div>
                   <h2 style={{opacity:this.state.opacity}}>react的生命周期</h2>
                   <button onClick={this.handleComponent}>卸载组件</button>
               </div>
           )
       }
    }
    // 渲染组件
    ReactDOM.render(<Demo />,document.getElementById("test"))
    
    

    理解

    组件从创建到死亡它会经历一些特定的阶段。

    React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。

    我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。

    生命周期流程图(旧)

    1. 初始化阶段: 由ReactDOM.render()触发---初次渲染

    (1)constructor()

    constructor()中完成了React数据的初始化,它接受两个参数:props和context,当想在函数内部使用这两个参数时,需使用super()传入这两个参数。
    注意:只要使用了constructor()就必须写super(),否则会导致this指向错误。

    (2)componentWillMount()

    它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。

    (3)render()

    render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。

    初始化渲染或更新渲染调用

    (4)componentDidMount()

    组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染。

    一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息

    2.更新阶段: 由组件内部this.setSate()或父组件重新render触发

    • 1)setSate更新状态 :shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate

    • 2)forceUpdate更新(不更改任何状态中的数据,强制更新一下):componentWillUpdate -> render -> componentDidUpdate

    • 3)父组件重新render触发:componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate

    componentWillReceiveProps (nextProps)

    • 在接受父组件改变后的props需要重新渲染组件时用到的比较多

    • 接受一个参数nextProps

    • 通过对比nextProps和this.props,将nextProps的state为当前组件的state,从而重新渲染组件

    shouldComponentUpdate(nextProps,nextState)

    • 主要用于性能优化(部分更新)

    • 唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新

    • 因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断

    componentWillUpdate (nextProps,nextState)

    shouldComponentUpdate返回true以后,组件进入重新渲染的流程,进入componentWillUpdate

    componentDidUpdate(prevProps,prevState)

    组件更新完成

    3.卸载组件: 由ReactDOM.unmountComponentAtNode()触发

    componentWillUnmount()

    一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

    
    class Count extends React.Component { 
      constructor(props){ 
          console.log("Count constructor");
          super(props);  
          // 初始化状态
          this.state = {
              num: 0
          } 
      } 
      // 方法
      add = () => {
          let { num } = this.state; 
          this.setState({
              num: num+1
          })
      } 
      //卸载组件按钮的回调
      death = ()=>{
        ReactDOM.unmountComponentAtNode(document.getElementById('test'))
      } 
      //强制更新按钮的回调
      force = ()=>{
        this.forceUpdate()
      } 
      //组件将要挂载的钩子
      componentWillMount() {
          console.log("Count componentWillMount")
      }  
      // 组件挂载完毕的钩子
      componentDidMount() {
          console.log("Count componentDidMount")
      }  
      //控制组件更新的“阀门”
      shouldComponentUpdate(){
        console.log('Count shouldComponentUpdate');
        return true
      } 
      // 组件将要更新的钩子
      componentWillUpdate(){
          console.log('Count componentWillUpdate');
      } 
      // 组件更新完毕的钩子
      componentDidUpdate() {
          console.log("Count componentDidUpdate")
      }  
      // 初始化渲染组件,状态更新之后 
      render() {
          console.log("Count render")
          return (
              <div>
                  <h2>当前求和:{this.state.num}</h2>
                  <button onClick={this.add}>点我+1</button>
                  <button onClick={this.death}>卸载组件</button>
    						<button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
              </div>
          )
      }
    }
    // 渲染组件
    ReactDOM.render(<Count />, document.getElementById("test"))
    
    
    // 父组件render 
    class A extends React.Component {
      state = {
          name:"张三"
      }
      changeName = () => {
          this.setState({
              name:"李四"
          })
      }
    
      render(){
          return (
              <div>
                  <h2>A组件</h2>
                  <B name={this.state.name}></B>
                  <button onClick={this.changeName}>改变名字</button>
              </div>
          )
      }
    }
    // 子组件
    class B extends React.Component { 
      //组件将要接收新的props的钩子
      componentWillReceiveProps(props){
        console.log('B---componentWillReceiveProps',props);
      }
      //控制组件更新的“阀门”
      shouldComponentUpdate(){
        console.log('B---shouldComponentUpdate');
        return true
      }
      //组件将要更新的钩子
      componentWillUpdate(){
        console.log('B---componentWillUpdate');
      }
      //组件更新完毕的钩子
      componentDidUpdate(){
        console.log('B---componentDidUpdate');
      }
      render(){
          console.log('B---render');
          return <h2>B组件:{this.props.name}</h2>
      }
    }
    ReactDOM.render(<A />, document.getElementById("test1"))
    

    生命周期流程图(新)

    1、初始化阶段: 由ReactDOM.render()触发---初次渲染

    constructor()

    getDerivedStateFromProps()

    render()

    componentDidMount()

    2、更新阶段: 由组件内部this.setSate()或父组件重新render触发

    getDerivedStateFromProps

    shouldComponentUpdate()

    render()

    getSnapshotBeforeUpdate

    getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()。

    componentDidUpdate()

    卸载组件: 由ReactDOM.unmountComponentAtNode()触发

    componentWillUnmount()

    即将废弃的勾子

    • componentWillMount

    • componentWillReceiveProps

    • componentWillUpdate

    现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。

  • 相关阅读:
    java接口鉴权之sign签名校验与JWT验证
    完整的后端开发流程-深入浅出Java线程池:使用篇
    Java多线程加法计算--Java识别静态验证码和动态验证码
    超全面设计指南:如何做大屏数据可视化设计?
    vue+echarts+datav大屏数据展示及实现中国地图省市县下钻
    开源」目前见过的最好的开源OA产品架构师之路(一):何时选用合适的语言
    如何做大屏数据可视化设计?
    Spring项目方便调试打印请求信息点击跳转到方法
    Echart生成的报表导出为PDF
    java环境变量一键配置
  • 原文地址:https://www.cnblogs.com/jing428/p/14505765.html
Copyright © 2011-2022 走看看