• React中生命周期的讲解


    什么是生命周期?

    从出生到成长,最后到死亡,这个过程的时间可以理解为生命周期。
    React中的组件也是这么一个过程。
    React的生命周期分为三个阶段:挂载期(也叫实例化期)、更新期(也叫存在期)、卸载期(也叫销毁期)。
    在每个周期中React都提供了一些钩子函数。
    生命周期的描述如下:
    挂载期:一个组件实例初次北创建的过程。
    更新期:组件在创建后再次渲染的过程。
    卸载期:组件在使用完后被销毁的过程。
    

    创建阶段(挂载阶段)

    创建阶段(挂载阶段)
    1==> constructor(){}
    <!-- 触发时机:创建组件,作用:初始化state中的数据, 可以为事件绑定this -->
    
    
    2==>render(){}
    <!-- 触发时机:每次组件渲染(初次渲染组件和更新组件)都会被触发,;作用是渲染UI; 注意不能够调用 setState
    为什么不能够在 render中使用 setState;因为setState会更新数据,这样会导致递归渲染数据。
    -->
    
    3==>componentDidMount(){}
    <!-- DOM已经渲染完成了;可以进行DOM操作和网络请求
    如果你在 constructor 和 render中获取DOM节点,得到的结果是null;
     -->
    

    更新阶段

    更新阶段
    有三种情况会导致组件的更新-触发render函数;
    1. 组件接收到一个新的属性,会进行渲染。-触发render函数
    2. 调用setState()组件会跟新。-触发render函数
    3. 调用forceUpdate()方法会跟新组件。-触发render函数
    上面这三种方法会触发render(){}函数
    更新阶段先触发
    1==> render函数 
    2==> 然后就是componentDidUpdate[当组件中的数据跟新完成后会触发]
    

    第一种[组件接收到一个新的属性]-触发render函数

    下面这个例子是,我们给组件赋值了props;
    组件触发了render函数这个生命周期
    
    父组件
    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    class Father extends React.Component{
      state  = {
        num:1
      }
      addHandler = () => { 
        this.setState({
          num:10
        })
      }
      render() { 
        return (
          <div>
            <button onClick={this.addHandler}>大豆豆</button>
            <ClassCom showNum={this.state.num}></ClassCom>
          </div>
        )
      }
    }
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    
    子组件
    import React from "react";
    class ClassCom extends React.Component{
        constructor(props) { 
            super(props)
            console.warn('子组件-声明周期钩子函数: constructor ')
        }
        render() { 
            console.warn('子组件-声明周期钩子函数: render ')
            return (
                <div>
                    <h2>我是组件</h2>
                    <p>我展示的声明周期钩子函数</p>
                    <p>显示的数量 { this.props.showNum }</p>
                </div>
            )
        }
    
        componentDidMount() { 
            console.warn('子组件-声明周期钩子函数: componentDidMount ')
        }
    }
    export default ClassCom
    

    第二种[调用setState()组件会跟新]-触发render函数

    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    class Father extends React.Component{
      state  = {
        num:1
      }
      addHandler = () => { 
        this.setState({
          num:this.state.num
        })
      }
    
      render() { 
        console.log('调用setState()组件会跟新-会触发render函数')
        return (
          <div>
            <p> 豆豆的数量是: { this.state.num }</p> 
            <button onClick={this.addHandler}>大豆豆</button>
          </div>
        )
      }
    }
    
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    

    第三种调用forceUpdate会触发render

    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    class Father extends React.Component{
      addHandler = () => { 
        // 强制跟新数据;会触发render函数
        this.forceUpdate()
      }
    
      render() { 
        console.log('调用setState()组件会跟新-会触发render函数')
        return (
          <div>
            <button onClick={this.addHandler}>强制更新</button>
            <p>我是内容,点击按钮,会触发render这个生命周期</p>
          </div>
        )
      }
    }
    
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    

    componentDidUpdate 的触发时机

    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    class Father extends React.Component{
      state  = {
        num:1
      }
    
      addHandler = () => { 
        // 强制跟新数据
        this.forceUpdate()
      }
    
      render() { 
        console.log('调用setState()组件会跟新-会触发render函数')
        return (
          <div>
            <button onClick={this.addHandler}>强制更新</button>
          </div>
        )
      }
    
      componentDidUpdate() { 
        console.warn('组件已经更新完成')
      }
    }
    
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    
    componentDidUpdate 钩子函数中
    如果要调用:1.setState()更新状态或2.者网络请求。
    必须包放一个if语句;否者会导致递归更新;
    因为调用 setState会触发render函数;render触发后,就会触发componentDidUpdate;
    这样就导致了-递归更新
    所以我们要放置一个判断语句;不让他出现递归更新就可以了
    比较更新前后的数据是否一样。如果一样就不进行更新了。
    componentDidUpdate(prevProps) { } 表示子组件已经更新完毕
    prevProps中可以获取上一个props的值
    

    componentDidUpdate函数参数prevProps的使用

    父组件
    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    class Father extends React.Component{
      state  = {
        num:1
      }
      addHandler = () => { 
        this.setState({
          num:this.state.num+10
        })
      }
      render() { 
        return (
          <div>
            <button onClick={this.addHandler}>增加</button>
            <ClassCom showNum={ this.state.num }></ClassCom>
          </div>
        )
      }
    }
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    
    子组件
    import React from "react";
    class ClassCom extends React.Component{
      render() { 
        return (
          <div>
            <h2>我是组件</h2>
            <p>显示的数量 { this.props.showNum }</p>
          </div>
        )
      }
      componentDidUpdate(prevProps) { 
        console.log('组件更新完毕', prevProps);
        if (prevProps.showNum !== this.props.showNum ) { 
          // 可以做发送Ajax的请求
          // 可以设置值 this.setState({})
          //这样就不会导致 递归更新了
        }
      }
    }
    export default ClassCom
    

    第三个阶段

    卸载阶段
    componentWillUnmount() { }
    组件将要卸载的时候会被触发,可以做清除定时器。
    下面当num>3的时候,ClassCom 组件将会被卸载。
    这个时候,componentWillUnmount生命周期将会被触发哈
    

    componentWillUnmount 的使用

    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    class Father extends React.Component{
      state  = {
        num:1
      }
      addHandler = () => { 
        this.setState({
          num:this.state.num+1
        })
      }
      render() { 
        return (
          <div>
            <button onClick={this.addHandler}>增加</button>
            { this.state.num > 3 ? <p>豆豆已经被你打死了</p> : <ClassCom showNum={ this.state.num }></ClassCom> }
            
          </div>
        )
      }
    
      componentWillUnmount() { }
    }
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    
    子组件
    import React from "react";
    class ClassCom extends React.Component{
        render() { 
            return (
                <div>
                    <h2>我是组件</h2>
                    <p>我是豆豆,被打了 { this.props.showNum } 次</p>
                </div>
            )
        }
        componentWillUnmount() { 
            console.log('组件已经被卸载了')
        }
    }
    export default ClassCom
    

  • 相关阅读:
    最常用和最难用的控件--ListView(Android第一行代码)
    LayoutInflater的使用
    JAVA的网络编程【转】
    Android 程序调试
    android Log日志使用
    Android Animation
    实现ImageView宽度填满屏幕
    Android ViewPager使用详解
    对另一个布局文件里的Button按钮进行监听
    如何在一个Activity里使用另一个xml布局文件
  • 原文地址:https://www.cnblogs.com/IwishIcould/p/16357466.html
Copyright © 2020-2023  润新知