• React 进修之路(2)


    生命周期

      React中的组件被看成是一个有生命的个体,因此赋予了声明周期的概念,就是为了定义组件所处的状态

        React中组件共分三大周期,11个阶段

          创建期(少年,成长)组件创建时候进入的时期

            getDefaultProps    getInitialState    componentWillDid    render  componentDidMount

          存在期(中年,反反复复的工作)组件内部数据(属性或者状态)更新时候进入的时期

            componentWillReceiverProps   shouldComponentUpdate   componentWillUpdate   render   componentDidUpdate

          销毁期(老年,消亡)组件从页面中删除时候进入的时期     

            componentWillUnmount
      

      下面我们来一一细说每个时期  

      创建期

        创建期是组件创建时候进入的时期,共分成五大阶段

        一旦组件创建完成,创建期就结束,就进入下个周期 --> 存在期

         1 创建默认属性数据 --> getDefaultProps

            没有参数

            作用域是构造函数,说明组件构造函数还没有执行完毕,所以不能访问组件实例化对象

            访问不了组件中任何的数据,方法

            返回值是默认的属性数据

         2 初始化状态数据 --> getInitialState

            没有参数

            作用域是组件实例化对象

            所以在这个方法中,可以访问属性数据了,但是不能访问状态数据

            所以工作中,我们通常在这个方法中用属性的数据,初始化状态数据

            这样就实现了将外部的数据,传递给内部更新维护

            返回值是初始化的状态数据

         3  组件即将被创建 -->  componentWillMount

            没有参数

            作用域是组件实例化对象

            在这个阶段,我们可以获取属性数据,可以获取状态数据,就是不能获取dom元素

            所以工作中通常会简单处理属性数据,或者状态数据,或者处理内部的方法,但是绝对不能更新属性数据或者状态数据,也不要为组件绑定元素绑定事件

         4  渲染输出组件 -->  render

            没有参数
            作用域是组件实例化对象

            不能获取dom元素(这个方法执行完毕才能获取),可以获取属性数据,可以获取状态数据

            返回值是渲染输出的虚拟dom元素

          5 组件创建完成 -->  componentDidMount

            没有参数

            作用域是组件实例化对象

            工作中很常用

            可以访问属性数据,可以访问状态数据,可以访问dom元素

            还可以在这里发送异步请求,请求数据更新状态

            还可以绑定事件

            还可以更新状态

        这个方法执行完毕就标志着组件创建期的结束

        获取组件对应的真实dom元素

          0.13版本之前

            this.getDOMNode()

            React.findDOMNode(this)

            都可以获取

          0.13版本之后

            只能使用ReactDOM.findDOMNode(this)

        

    1var GoTop = React.createClass({
    2    // 第一个阶段 初始化默认属性
    3    getDefaultProps: function () {
    4        console.log(111, this)
    5        console.log(111, arguments)
    6        return {
    7            text: '分类网址'
    8        }
    9    },
    10    // 第二个阶段 初始化状态
    11    getInitialState: function () {
    12        console.log(222, this)
    13        console.log(222, arguments)
    14        // console.log(this.state)
    15        return {
    16            color: 'red',
    17            // 用属性数据更新状态
    18            text: this.props.text
    19        }
    20    },
    21    // 第三个阶段 组件即将构建
    22    componentWillMount: function () {
    23        console.log(333, this)
    24        console.log(333, arguments)
    25        // 获取虚拟dom对应的真实的dom元素
    26        // console.log(ReactDOM.findDOMNode(this))
    27        // console.log(this.props)
    28        // console.log(this.state)
    29    },
    30    // 第四个阶段 渲染组件
    31    render: function () {
    32        console.log(444, this)
    33        console.log(444, arguments)
    34        // console.log(ReactDOM.findDOMNode(this))
    35        // 渲染输出虚拟dom
    36        return (
    37            <div className="go-top">
    38                {/*这里的文案实时改变,需要在内部围护,因此要使用状态数据*/}
    39                <span onClick={this.goTop}>{this.state.text}</span>
    40            </div>
    41        )
    42    },
    43    // 返回顶部的方法
    44    goTop: function () {
    45        if (this.state.text === '返回顶部') {
    46            window.scrollTo(0, 0)
    47        }
    48    },
    49    // 第五个阶段 组件构建完成
    50    componentDidMount: function () {
    51        console.log(555, this)
    52        console.log(555, arguments)
    53        // 获取虚拟dom对应的真实的dom元素
    54        // console.log(ReactDOM.findDOMNode(this))
    55        // react以及组件实例化对象上的不建议使用了
    56        // console.log(React.findDOMNode(this))
    57        // console.log(this.getDOMNode())
    58
    59        // 事件在最后一个阶段绑定
    60        window.onscroll = function () {
    61            // console.log(111)
    62            // 滚动200更改文案
    63            if (window.scrollY > 200) {
    64                this.setState({
    65                    text: '返回顶部'
    66                })
    67            } else {
    68                this.setState({
    69                    text: '分类网址'
    70                })
    71            }
    72        }.bind(this)
    73    }
    })

    在说下一个生命周期之前,插入一个小知识点

      子组件 

         在组件中使用的组件,叫该组件的子组件,在组件中使用子组件很简单,跟使用虚拟DOM元素一模一样

    <Slider>
        <GoTop color=“red” />
    </Slider>

        这里定义的GoTop组件就叫Slider组件的子组件

        在组件中可以为子组件添加属性,添加的属性就是对子组件传递的数据

        传递的数据分成四类

          1 如果属性值是一个变量(字符串,对象等)

            传递给子组件的数据不会改变

          2 如果属性值是父组件中的属性数据

            传递给子组件中的数据往往不会改变(除非父组件也是一个子组件)(因为组件的属性数据只能在外部改变,如果父组件是其他组件的子组件,父组件的属性数据可能会改变,此时传递给子组件的数                        据就可能发生改变)

          3 如果属性值是父组件中的状态数据

            如果父组件中状态数据发生了改变,那么传递给子组件的数据就发生了改变

          4 如果属性值是父组件中的方法

            父组件提供的方法作为子组件的事件回调函数,作用域仍然是父组件

            回调函数两个参数

              第一个是react封装的事件对象

              第二个是源生的事件对象

            如果父组件提供的方法在子组件的方法内执行,没有参数了,但作用域依旧是父组件

              (搞不清楚的童鞋们请注意观察下列代码的第26行和29行)

          这里的数据传递,父组件将数据传递给子组件,本质上就是父组件向子组件通信

      

     1 // 创建GoTop组件
     2 var GoTop = React.createClass({
     3     // 定义默认状态数据
     4     getDefaultProps: function () {
     5         return {
     6             text: '网址导航'
     7         }
     8     },
     9     // 定义初始化状态
    10     getInitialState: function () {
    11         return {
    12             // 用属性数据赋值状态数据
    13             text: this.props.text
    14         }    
    15     },
    16     // 返回顶部的方法
    17     goTop: function () {
    18         // console.log(111,arguments)
    19         // console.log(222,this);
    20         // 在子组件的方法中使用父组件提供的方法
    21         this.props.goBackByParent()
    22     },
    23     render: function () {
    24         console.log(this)
    25         // 渲染输出虚拟DOM
    26         // <span onClick={this.props.goBackByParent}>{this.props.text}</span>
    27         return (
    28             <div className="go-top">
    29                 <span onClick={this.goTop}>{this.props.text}</span>
    30             </div>
    31         )
    32     }
    33 })
    34 
    35 // 定义slider组件
    36 var Slider = React.createClass({
    37     // 定义属性
    38     getDefaultProps: function () {
    39         return {
    40             title: '头条新闻'
    41         }
    42     },
    43     // 定义状态数据
    44     getInitialState: function () {
    45         return {
    46             text: '新闻头条'
    47         }
    48     },
    49     // 渲染输出虚拟dom
    50     render: function () {
    51         return (
    52             <div className="slider">
    53                 {/*GoTop 就是Slider的子组件*/}
    54                 <GoTop color="red" title={this.props.title} text={this.state.text} goBackByParent={this.goBack} />
    55             </div>
    56         )
    57     },
    58     // 定义返回顶部方法
    59     goBack: function () {
    60         console.log(123, this, arguments)
    61     },
    62     // 定义滚动事件
    63     componentDidMount: function () {
    64         window.onscroll = function () {
    65             if (window.scrollY > 200) {
    66                 this.setState({
    67                     text: '返回顶部'
    68                 })
    69             } else {
    70                 this.setState({
    71                     text: '网址导航'
    72                 })
    73             }
    74         }.bind(this)
    75     }
    76 })
    77 
    78 // 将组件渲染到页面中
    79 ReactDOM.render(<Slider />, document.getElementById('app'))

      存在期

      存在期也有五个阶段

      这五个阶段方法的作用域都是组件实例化对象,因此这个五个阶段都能访问组件中的属性和状态,当然还有虚拟DOM

      6 组件即将接收新的属性 -->  componentWillReceiveProps

        有一个参数表示新的属性对象

        工作中经常在这个阶段用新的属性对象,更新状态数据

        这个方法只有在属性更新的时候,会执行,状态更新的时候不会执行

      7  组件是否应该更新 --> shouldComponentUpdate

        有两个参数

          第一个参数表示新的属性

          第二个参数表示新的状态

        通过作用域可以访问原来的属性,原来的状态,原来的dom

        必须有返回值

          True表示可以继续更新

          False表示不能继续更新

        我们可以通过设置false属性来优化组件更新的频率

      8  组件即将更新 --> componentWillUpdate

        有两个参数

          第一个参数表示新的属性

          第二个参数表示新的状态

        通过作用域可以访问原来的属性,原来的状态,原来的dom

        在这个阶段,一定不要再更新属性或者状态了

        属性或者状态数据,在这个阶段更新完毕的

      9 组件即将渲染输出新的虚拟DOM --> Render(这里的render方法跟创建期是同一个)

        通过作用域可以访问新的的属性,新的的状态,原来的dom

        在这里绝对不能操作原来的dom,因为在创建期也使用这个方法(在创建期的render方法中是不能访问dom的)

      10 组件更新完毕 --> componentDidUpdate

        有两个参数

          第一个表示原来的属性对象

          第二个表示原来的状态对象

        是最后一次可以访问到原来的属性数据或者状态数据了

        通过作用域可以访问新的的属性,新的的状态,新来的dom

        这个方法执行完毕,组件存在期就完成一次更新,我们可以在这个方法中再次更新属性,再次更新状态,发送请求,绑定事件等等

        当组件中属性数据或者状态数据发生了改变的时候,会进入该周期

      1 // 创建GoTop组件
      2 var GoTop = React.createClass({
      3     // 定义默认状态数据
      4     getDefaultProps: function () {
      5         return {
      6             text: '网址导航'
      7         }
      8     },
      9     // 定义初始化状态
     10     getInitialState: function () {
     11         return {
     12             // 用属性数据赋值状态数据
     13             text: this.props.text
     14         }    
     15     },
     16     // 返回顶部的方法
     17     goTop: function () {
     18         console.log(111)
     19     },
     20     render: function () {
     21         console.log(4, this.state.text)
     22         console.log(4, arguments)
     23         // 渲染输出虚拟DOM
     24         return (
     25             <div className="go-top">
     26                 <span onClick={this.props.goBackByParent}>{this.state.text}</span>
     27             </div>
     28         )
     29     },
     30     // 更新状态
     31     componentDidMount: function () {
     32         // var me = this;
     33         // setTimeout(function () {
     34         //     me.setState({
     35         //         text: '返回顶部'
     36         //     })
     37         // }, 1000)
     38         window.onscroll = function () {
     39             // console.log(111)
     40             // 滚动200更改文案
     41             if (window.scrollY > 200) {
     42                 this.setState({
     43                     text: '返回顶部'
     44                 })
     45             } else {
     46                 this.setState({
     47                     text: '分类网址'
     48                 })
     49             }
     50         }.bind(this)
     51     },
     52     // 第一个阶段是 组件即将接收新的属性
     53     componentWillReceiveProps: function(newProps) {
     54         console.log(1, this)
     55         console.log(1, arguments)
     56         // 用属性数据更新状态
     57         this.setState({
     58             text: newProps.text
     59         })
     60     },
     61     // 第二个阶段 组件是否应该更新
     62     shouldComponentUpdate: function (newProps, newState) {
     63         console.log(2, this)
     64         console.log(2, arguments)
     65         console.log(ReactDOM.findDOMNode(this).innerHTML)
     66         // 组件状态text值更新时候,进入存在期,
     67         // 判断新的text值与旧的text值的变化
     68         if (newState.text !== this.state.text) {
     69             return true;
     70         } else {
     71             return false
     72         }
     73         // return false
     74     },
     75     // 第三个阶段 组件即将更新
     76     componentWillUpdate: function() {
     77         console.log(3, this.state.text)
     78         console.log(3, arguments)
     79     },
     80     // 第五个阶段 组件更新完毕
     81     componentDidUpdate: function() {
     82         console.log(5, this)
     83         console.log(5, arguments)
     84         console.log(ReactDOM.findDOMNode(this).innerHTML)
     85 
     86     }
     87 })
     88 
     89 // 定义slider组件
     90 var Slider = React.createClass({
     91     // 定义属性
     92     getDefaultProps: function () {
     93         return {
     94             title: '头条新闻'
     95         }
     96     },
     97     // 定义状态数据
     98     getInitialState: function () {
     99         return {
    100             text: '新闻头条'
    101         }
    102     },
    103     // 渲染输出虚拟dom
    104     render: function () {
    105         return (
    106             <div className="slider">
    107                 {/*GoTop 就是Slider的子组件*/}
    108                 <GoTop color="red" title={this.props.title} text={this.state.text} goBackByParent={this.goBack} />
    109             </div>
    110         )
    111     },
    112     // 定义返回顶部方法
    113     goBack: function () {
    114         console.log(123, this, arguments)
    115     },
    116     // 定义滚动事件
    117     componentDidMount: function () {
    118         
    119     }
    120 })
    121 
    122 // 将组件渲染到页面中
    123 ReactDOM.render(<Slider />, document.getElementById('app'))

     销毁期

      销毁期:当组件从页面中删除,组件就进入了销毁期

        11 销毁期只有一个阶段 --> componentWillUnmount

          没有参数

          作用域是组件实例化对象

        这个方法是能够访问组件的最后一次机会了,这个方法执行完毕之后,组件就销毁了

     1 // 定义返回顶部组件
     2 var GoBack = React.createClass({
     3     render: function () {
     4         return (
     5             <div className="go-back">
     6                 <span>返回顶部</span>
     7             </div>
     8         )
     9     },
    10     // 定义组件销毁期的阶段
    11     componentWillUnmount: function () {
    12         console.log(this)
    13         console.log(arguments)
    14     }
    15 })
    16 
    17 // 将组件渲染到页面中
    18 ReactDOM.render(<GoBack />, document.getElementById('app'))
    19 
    20 // 3秒钟之后渲染h1
    21 setTimeout(function () {
    22     ReactDOM.render(<h1>啦啦啦,我是文字</h1>, document.getElementById('app'))
    23 }, 3000)
  • 相关阅读:
    float浮动
    数据库基础操作
    Python re 模块
    I/O模型的使用
    函数形参与实参
    内置函数重写_运算符重载
    导入模块_导入包_标准库模块
    异常处理
    闭包
    函数式编程
  • 原文地址:https://www.cnblogs.com/bandeng/p/6562114.html
Copyright © 2020-2023  润新知