二、react面向组件编程(一)

摘要: 以前我们熟悉的jquery编程的方式是以面向对象的方式来进行编程的,而react将这种编程方式提升了一个层级,及面向对象---》 面向模块 ----》 面向组件。react面向组件编程无非两个步骤,定义组件和渲染组件。接下来将学习如何定义组件,以及渲染组件。

1. react组件的分类

  • 函数式组件
  • es6类组件
    这两种组件接下来会一一了解到。

2. 自定义组件

2.1) 工厂函数组件(简单组件)如

// 函数式组件必须要有个return
function MyComponent () {
 return 

函数式组件

}

以下用用函数式组件编写最简单的demo



  
    
    react-demo1
  
  
    

2.2) es6类组件(复杂组件)如

  // 这种方式继承了React的核心组件,并重写了render方法,类实例通过调用render方法来创建虚拟dom
    class MyComponent extends React.Component{
        render () {
          return 

学习react类组件

} }

以下是基于类组件最简单的demo:



  
    
    react-demo1
  
  
    

这里分析类了组件如何定义使用,到这里心中应该有个疑问,既然是类,那么他的人实例应该长什么样子?类组件重写了React的render方法,这个render方法一定是由组件类的实例所调用的,因此在render的方法中是可以访问到这个实例的,其实就i是常见的this,所以有必要在render中打印this一探究竟,如下:

 

通过打印this得到如下的结果:


image.png

可以看到有属性,有方法。接下来我们就来看看这些属性和方法的作用,(
红色框起来的是重点),究竟是用来干嘛的。

3. 组件三大属性

  • state(react的思想是尽量少操作dom或者不操作dom,而是通过操作数据来改变视图,要操作的数据其实就是state,这个state其实就是组件对象最重要的属性,值是对象,可以包含多个数据,react组件也因此可以叫做状态机,通过更新组件的state来更新对应的页面显示)那么问题就来了,如何初始化这些状态?如何读取某个状态,如何更新某一个状态?这些问题通过以下编码demo的方式来阐述,。
/**
* 首先要先知道以下几点:
* 1. 在构造器中进行初始化操作,react 类组件提供了构造器
* 2. 要更新状态要通过事件触发,那么如何绑定事件
* 3. 通过setState来更新状态的值,更新状态前可能需要读取状态
*
*****/


  
    
    react-demo1
  
  
    

这个示例尽管简单,但是说明了几个问题,1.修改状态数据确实能改变视图,体现了react的数据驱动思想,2.设置更新状态唯一的方式是通过setState方法,3.通过this.state.属性可以直接获取状态。4.如何进行事件绑定以及this指向的问题的。

  • props属性(state是组件内部的状态,这似乎在有些情况下只有state是不能满足需求的,比如说,自定义一个显示年龄信息的组件,要求显示姓名,性别,年龄,很明显这些要显示的信息不是组件内部特有的属性,而应该是传递给组件的属性,传递给组件的属性其实就是props,很显然这个组件是没有state的,那么可以通过工厂函数组件的方式来创建,函数组件是没有state的,函数组件比类组件效率高,因为函数可以直接调用,而类必须先创建对象,才能调用render函数),接下来就来编写这个年龄信息组件。


  
    
    react-demo1
  
  
    

这个demo很明显的说明了props的作用,传递给组件Person的属性全部由props接收。但是上面的这个例子还有一些小缺陷,比如,如果age,sex没有传递给组件,呢么Person组件是拿不到age,和sex的。name能不能再age和sex没有被传递的情况下给一个默认值了?如果组件要求name必须传递,age需要传递数值类型的,该如何验证了?首先说明一下,组件是可以给默认值得,也可以做类型和唯一校验的,接下来就添加这些规则:



  
    
    react-demo1
  
  
    

该demo虽然简单,但是从从如何传递props,如何做规则校验,如何给默认值都做了说明,可谓麻雀虽小。

  • refs(react尽量不要操作dom,但是有时候不得不操作dom,那么,refs就是用来获取dom元素的,对于设置了ref属性的虚拟dom,可以通过refs属性来获取到dom)这里用一个小demo来阐述一下:


  
    
    react-demo1
  
  
    

这个小demo解释了refs属性的用法,通过ref标记dom元素,通过refs来获取dom元素,当然ref可以是字符串,也可以是回调函数,上面例子中的 this.input = input}/>   就是采用回调的方式,而且这种写法优雅,因为获取dom一次就被存起来了,不用每次都获取。

4. 组件组合使用(组件化)

组件化编程无非以下几个步骤:

  1. 拆分组件: 拆分界面,抽取组件
  2. 实现静态组件: 使用组件实现静态页面效果
  3. 实现动态组件: 动态显示初始化数据,交互功能(从绑定事件监听开始)

比如:实现如下图所示的todoList 案例demo:
image.png

根据以上三个步骤进行编码工作 ,第一步其实就是图示的拆分方式,第二步编写三个静态组件,第三步做交互,改为动态组件。

// 编写静态组件


  
    
    react-demo1
  
  
    

至此,静态组件已经编写完成了,接下来就是改成动态组件,首先需要明确几个问题,这里有三个组件APP,Add,List。那么我们应该吧数据状态放在那个组件中?到这里我们必须明确知道到底需要哪些数据,其实这里只要一个list列表数据就可以了,我们可以称其为todos,这些数据是哪些组件使用的?很明显Add组件用,因为他要往里面添加数据,List也需要,因为他要读取。因此最好的方式是放在App中,因为App是他们共同的父组件,而且todos需要被Add和List共享。由此可以总结为:看数据是某一个组件需要还是某些组件需要,如果是某一个组件需要则放在组件内部,如果是某些组件需要,则放在他们公共的父组件中。



  
    
    react-demo1
  
  
    

此demo初步体现了组件化编程的思想。

5. 收集表单数据

表单在开发中都会用到,在react中,将表单组件分为受控和非受控两种,受控组件就是指表单项输入数据能够自动收集成状态,非受控组件是指需要表单项的值时手动读取表单输入框中的数据,以下通过demo来具体说明以下:



  
    
    react-demo1
  
  
    
/** * 这段代码中,受控项是密码输入框,在输入的时候,会自动收集输入框的值到state* 中,非受控项是用户名输入框,当需要输入框中的值的时候必须手动获取,如 const username = this.nameInput.value 就是在用到的时候才获取的 * * **/

以上就是对受控组件和非受控组件的阐述,从代码的简洁性上非受控组件简单,因为非受控组件不需要绑定onChange事件之类的。但是从react的思想出发,受控组件优于非受控组件,因为非受控组件其实就是在操作dom.

6.组件声明周期(组件从生到死的过程)

生命周期流程:
  (一).第一次初始化渲染

  • constructor(): 创建对象初始化state
  • componentWillMount(): 将要插入虚拟dom的回调
  • render(): 用于插入虚拟dom回调
  • componentDidMount(): 已经插入虚拟dom的回调
      (二).每次更新state: this.setState()
    *componentWillUpdate(): 将要更新回调
    *render(): 更新(重新渲染)
    *componentDidUpdate(): 已经更新的回调
      (三).移除组件ReactDom.unmountComponentAtNode(containerDom)
  • componentWillUnmount(): 组件将要被移除的回调

重要的几个钩子函数:

  • render(): 初始化渲染或者更新渲染调用
  • componentDidMount(): 开启监听,发送ajax请求
  • componentWillUnmount(): 组建将要卸载,做一些收尾工作,如清理定时器
  • componentWillReceiveProps(): 接收父组件属性的钩子

你可能感兴趣的:(二、react面向组件编程(一))