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

  • 相关阅读:
    IPC总结学习
    机器学习中的范数规则
    机器学习的几个误区-转载
    来几道大数据的面试题吧
    海量数据随机抽样问题(蓄水池问题)
    字符串类算法题目总结
    RPC学习
    如何做出健壮的系统设计
    关于bind函数和connect函数的测试结论
    [置顶] Codeforces Round #197 (Div. 2)(完全)
  • 原文地址:https://www.cnblogs.com/qianbin/p/10148755.html
Copyright © 2011-2022 走看看