React开发

React有Facebook内部项目而来,意在确定一套团队之间的开发规范,之后在2013年5月开源。之前团队一直在使用Vue.js,近期有了空挡,同时考虑到以后有移动端开发的需求,使用React-Native,于是从React入手,撸一把,以下纯属个人理解,如有欠妥的地方请指正。

一、初识

React是一个颠覆式前端UI开发框架。设计核心是“数据驱动”,状态(state)的变化,推动视图(DOM)的变化。组件化(Component)的开发思路,配合自身状态的管理,使app的开发简单、快速,同时提高了复用性。以下例子都是在ES6的基础上开发。

二、组件

可以认为React的最小单位就是一个组件,管理着自身的状态(state)与模板(render)。一个组件有不同的生命周期,不同阶段完成不同工作。

创建一个组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React, { Component } from 'react'
import { render } from 'react-dom'
//组件创建
class MyComponent extends Component {
constructor(props) {
super(props)
...初始化state
}
render() {
...template
}
...创建实例方法或者进行生命周期注册
}
//挂载到DOM上
render(
<App />
, document.getElementById('react-app'))

组合组件

两种方式:

  1. 直接在render函数中作为一个DOM引入

    1
    2
    3
    <div>
    <Children />
    </div>
  2. 从组件标签里引入子元素,需要在父元素通过this.props.children获取,由于this.props.children类型不确定(数组或者对象),需要借助React.Children的工具函数操作

    1
    2
    3
    <Parent>
    <Children />
    </Parent>

组件类型

展示组件(Presentational) 容器组件(Container)
作用 专注于页面长什么样 专注于如何运行
直接使用Redux
数据来源 props store
数据修改 从props调用回调函数 向Redux派发action
调用方式 手动 通常有React Redux生成

组件通信

  1. 父子组件通信

    将父组件的state作为props传给子组件,通过改变父组件的state,通知子组件变化

    父组件将方法通过state传递给子组件,子组件通过props调用父组件的方法,实现子组件修改父组件

  2. 兄弟节点通信

    都通过父组件通信

    通过this.context调用祖先组件,实现数据和方法的共享

  3. ​将状态全部交个第三方管理(Redux以后会介绍)

1. state

用来存放自身状态,状态是会发生变化的,状态的变化会引起DOM的变化,一般在构造函数(constructor)设置初始化状态。改变状态需要调用setState(nextState)方法,setState将原有状态和改变的状态做了一次合并,实现状态的更新。

2. props

从父组件获取的属性。可以通过propsTypes对props进行类型检测,通过defaultProps对props设置默认值。

3. componentWillMount(挂载)

  • 触发时机:挂载之前,render执行前
  • 改变state不会额外触发render函数

4. componentDidMount(挂载)

  • 触发时机:挂载之后,render执行后
  • 可以通过ReactDOM.findDOMNode(this)获取组件的Dom组件

5. componentWillReceiveProps(nextProps)(更新)

  • 触发时机:当一个挂载的组件接收到新的props的时候被调用

6. shoundComponentUpdate(nextProps, nextState)(更新)

  • 触发时机:组件做出是否要更新DOM的决定的时候被调用
  • 可以在该阶段对props和state的变化作比较,如果函数返回false,则停止更新DOM

7. componentWillUpdate(nextProps, nextState)(更新)

  • 触发时机:组件更新之前

8. componentDIdUpdate(preProps, preState)(更新)

  • 触发时机:组件更新之后

9. componentWillUnmount(移除)

  • 触发时机:组件卸载之前

三、JSX

javascript和xml混合编写的语法糖,原生HTML标签和React组件的区别是通过大小写区别的,大写开头的变量时React组件。

注意:Html中的class要写成classNamefor要写成htmlFor,因为classfor均为JavaScript的保留字

style属性只接受有CSS属性组成的object,样式名称必须和CSS一致,使用驼峰命名。

属性扩散

设置不确定的props

1
2
3
4
5
var props = {}
props.name = 'zhang'
props.age = 10
var component = <Component {...props} />

四、Virtual DOM

React将实际DOM映射到Virtual DOM(object)上,在数据发生变化,通过diff算法查找要变化的Virtual DOM,再讲实际变化更新到实际DOM上。

浏览器渲染DOM是很耗性能的,性能的瓶颈也往往在此。虚拟DOM让我们肆意地改变状态,无需关系性能问题,有虚拟DOM实现DOM的操作,只对实际变化的节点进行更新。实际上React的DOM操作还是在原生的API基础上的,到底他是如何实现这种“性能保证”的,我还没搞清,包括diff算法,之后有时间会对这部分专门学习一下。但是了解过程对我们的React开发还是很有帮助的。