zoukankan      html  css  js  c++  java
  • 笔记----深入浅出《React和Redux》第二章

    一、prop和state

    1、易于维护组件的设计要素

    (1)高内聚:把逻辑紧密的相关内容放在一个组件中

    (2)低耦合:不同组件之间的依赖关系尽量弱化

    2、React组件的数据

         分两种(都会引发组件的重新渲染):

        prop:组件对外接口;(一般用在组件之间传参)

                state:组件内部状态;(一般用在组件内部初始化)

         

    3、React的prop:组件的prop很像是HTML元素的属性,但是HTML元素的属性值都是字符串,而React组件的prop所支持的类型几乎包含人一JS中所支持的类型

       注意:

                  <SampleButton id=” sample”  borderWidth={2}  onClick={onButtonClick}   style={{color: ” red”}}  />

        style值中的{{}} , 外层表示JSX语法,内层表示对象

       (1)赋值 

          引入主入口组件App(另一个组件是第一章的demo)

                      

                     

          向三个ControlPanel的子组件Counter进行赋值,使用了caption和initValue两个prop

           

      (2)读取prop值

                     

                     通过props 进行 读取值

          结果显示:

                         

       (3)propType进行prop接口规范 

                                 

                      此时对prop值进行了约束,

                                对caption必须是string,并且isRequired表示caption为必填值

                                对initValue必须为number

                      如果不按约束标准进行,如

                                 

                     则报错 

                                

         注意:

                        即使在上面 propTypes 检查出错的情况下,组件依旧能工作 。 也就是说 propTypes检查只是一个辅助开发的功能,并不会改变组件的行为。

           

    4、React的state:帮助记录组件自身的数据变化

                  注意:组件的state必须是JS对象,不能是其他数据类型

      (1)初始化值

                

        可以换一种更优雅的写法

                

               一样可以实现默认值为0的效果

      (2)读取和更新state

                

        

        如果不使用setState(),修改代码如下

           

           此时点击“+”,则会弹出警告

            

         注意:

          在不使用setState()情况下,当连续点击10次“+”,数值并没有发生改变

                    

              然后再次点击“-”时,数值直接变成9

                

          可以看出在我们连续点击“+”,其实state值已经开始进行累加,但是没有渲染到页面上,当我们点击“-”时,使用setState(),将减去1之后的结果9显示在页面上

          总结:直接使用state修改值,只修改了内部状态,并没有引起重新渲染

     

    5、prop和state的对比

          (1)prop定义外部接口,state记录内部状态

      (2)prop的赋值在组件外部,state的赋值在组件内部

        (3)组件不应该改变prop的值,而state的值允许被修改

        (

          组件不应该改变prop的值的原因:

                 假设一个场景,父组件包含多个子组件,然后将一个JS对象作为prop值传给这几个子组件,而某个子组件修改了这个对象的内部值,

                            那么其他子组件在读取那个对象的值时都会受到影响,导致程序混乱

            

            书上没有实践案例,自己写个小demo测试一下(将之前代码都放demo1了,此次新创建demo2),如下:

              

              

              首先,将父组件引入主入口文件

                                            

               在Parent组件中,初始化content对象,并将它作为prop值,分别传入两个子组件

               

              

              

              ChildOne组件对prop值进行直接修改,ChildTwo组件中对prop值进行显示,观察prop值是否变化

              

              结果:

              

              先点击ChildOne,然后点进ChilTwo进行显示,发现prop值在子组件Children发生改变,丢失了最初的值

               

                        

              

                   )    

     二、组件的生命周期(v16.6.0)

        截取react官网生命周期图

                                                             

           (1)装载过程(Mount):组件第一次在DOM树中渲染过程;

           (2)更新过程(Update):当组件被重新渲染过程;

           (3)卸载过程(Unmount):组件从DOM中删除的过程;

       

    1、装载过程的对应函数:

    (1)constructor:当创建组件类的实例时,会调用对应构造函数

           注意:无状态的React组件,不需要定义构造函数

         

       React组件定义构造函数的目的:

                    (i)初始化state

                    (ii)绑定成员函数的this环境

    注意:

          在ES6语法下,类的每个成员函数在执行时的this并不是和类实例自动绑定的,而在构造函数中,this就是当前组件的实例

      所以,为了方便将来的调用,在构造函数中将这个实例的特定函数绑定this为当前实例。

     如:

       this .onClickincrementButton = this .onClickincrementButton.bind(this);

          

    (2)render:React组件中最重要的函数,一个React组件可以不实现其他所有函数,但是一定要实现render函数

        (i)某些特殊组件不是用来渲染界面,就让render函数返回一个null或者false,等于告诉React,这个组件不需要渲染DOM元素

                (ii)render函数是一个纯函数,根据this.state和this.props决定返回结果,不能在里面进行this.setState改变状态

           

    (3)componentWillMount和componentDidMount:

        (i)componentWillMount:这个函数在渲染前被调用,几乎不会被使用到,因为所有可以在这个 component­WillMount 中做的事情,都可以提前到 constructor 中间去做

                (ii)componentDidMount:这个函数被调用时,组件已经被装载到DOM树上了

    注意:

                    

                 执行顺序,结果:

        

      

               可以看出componentWillMount紧贴着自己组件的render函数之前被调用,componentDidMount在三个组件的render函数都被调用之后,

              三个组件的componentDidMount才连着被一起调用。

             

     原因:

           是因为 render 函数本身并不往 DOM 树上渲染或者装载内容,它只是返回一个 JSX表示的对象,然后由 React库来根据返回对象决定如何渲染。而 React库肯定是要把所有组件返回的结果综合起来,才能知道该如何产生对应的 DOM修改。 所以,只有 React库调用三个 Counter组件的 render函数之后,才有可能完成装载,这时候才会依次调用各个组件的 componentDidMount 函数作为装载过程的收尾 。

                    

         (iii)componentWillMount可以在服务器端或浏览器端被调用,componentDidMount只能在浏览器端被调用

                 (iv)在 componentDidMount 被调用的时候,组件已经被装载到 DOM 树上了,可以配合其他的第三方UI库(如:jQuery),进行添加新的功能

    2、更新过程的对应函数:

    (1)componentWillReceiveProps(nextProps)

                  (i)通过 this.setState方法触发的更新过程不会调用这个函数;

                  (ii)只要是父组件的render函数被调用,在render函数里面被渲染的子组件就会经历更新过程,

                       不管父组件传给子组件的props有没有改变,都会触发子组件的componentWillReceiveProps函数

      根据如下例子证明:

        父组件

        

            当触发onClick事件时,引发一个匿名函数,通过forceUpdate进行重新绘制(每个React组件都可以通过forceUpdate函数强行进行重新绘制)

        子组件

        

        

        运行结果

         

         显示页面初始化的数据,当进行点击Click me to repaint!时

        

               

        此时可以看出:

                         执行次序是当父组件的render被调用后,引发了子组件中componentWillReceiveProps的调用,最后子组件中的render也被调用了;

           再次渲染子组件时,它们的props并没有变化,但是子组件中componentWillReceiveProps依然被调用了  (有需要在子组件对nextProps和this.props值进行比较)

        再验证一下this.setState能不能触发componentWillReceiveProps

                             

        此时可以看出:                                      

           当前组件调用this.setState函数,不会引发componentWillReceiveProps函数             

        

    (2)shouldComponentUpdate(nextProps,nexState):除了render之外最重要的函数,通过返回的布尔值决定什么时候组件不需要渲染,

             (i)如果我们要定义 shouldComponentUpdate,那就根据这两个参数,外加 this.props和 this.state来判断是返回true,还是false,来避免重复渲染

       (ii)通过this.setState函数引发更新过程,并不是立刻更新组件的state值,在执行到函数shouldComponentUpdate的时候,this.state依然是this.setState函数执行之前的值 

        如:

         

         运行结果:

                

        可以看出,三个Counter组件的render函数没有被调用,因为这个刷新没有改变caption值或count,减少了不必要的渲染

    (3)componentWillUpdate和componentDidUpdate

        (i) componentDidUpdate函数,不仅在浏览器端可以执行,服务器端也可以执行

        (ii)在配合其他第三方UI库时(如:jQuery),当React组件被更新时,原有内容会被重新绘制,这时候需要在componentDidUpdate函数再次调用jQuery代码

    3、卸载过程的对应函数:

      (1)componentWillUnmount:当React组件要从DOM树上删除之前,此函数会被调用,适合做一些清除工作(如:防止内存泄漏)

    三、组件向外传递数据         

                             

          

            

            通过onUpdate这个prop值为onCounterUpdate函数,作为“桥梁”,通过函数的参数进行“沟通”

    其他参考:https://react.docschina.org

  • 相关阅读:
    [模板] 循环数组的最大子段和
    [最短路][几何][牛客] [国庆集训派对1]-L-New Game
    [洛谷] P1866 编号
    1115 Counting Nodes in a BST (30 分)
    1106 Lowest Price in Supply Chain (25 分)
    1094 The Largest Generation (25 分)
    1090 Highest Price in Supply Chain (25 分)
    树的遍历
    1086 Tree Traversals Again (25 分)
    1079 Total Sales of Supply Chain (25 分 树
  • 原文地址:https://www.cnblogs.com/qianbin/p/10148755.html
Copyright © 2011-2022 走看看