React学习02
React面向组件编程、React脚手架、ReactAjax
React学习02-MakerLi

第2章:React面向组件编程

2.1 基本理解和使用

2.1.1自定义组件(Component) :

1)定义组件(2种方式)

/*方式1: 工厂函数组件(简单组件)*/
function MyComponent () {
 return <h2>工厂函数组件(简单组件)</h2>
}

/*方式2: ES6类组件(复杂组件)*/

class MyComponent2 extends React.Component {
 render () {
  console.log(this) // MyComponent2的实例对象
  return <h2>ES6类组件(复杂组件)</h2>
 }
}

2)渲染组件标签

ReactDOM.render(<MyComponent />, document.getElementById('example1'))

2.1.2注意

  • 组件名必须首字母大写
  • 虚拟DOM元素只能有一个根元素
  • 虚拟DOM元素必须有结束标签

2.1.3 render()渲染组件标签的基本流程

  • React内部会创建组件实例对象
  • 得到包含的虚拟DOM并解析为真实DOM
  • 插入到指定的页面元素内部

2.2. 组件三大属性1: state

2.2.1. 理解

  • state是组件对象最重要的属性, 值是对象(可以包含多个数据)
  • 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

2.2.2. 编码操作

1)初始化状态:

 constructor (props) {
  super(props)
  this.state = {
   stateProp1 : value1,
   stateProp2 : value2
  }
 }

2)读取某个状态值

 this.state.statePropertyName

3)更新状态---->组件界面更新

 this.setState({
  stateProp1 : value1,
  stateProp2 : value2
 })

2.3. 组件三大属性2: props

2.3.1. 理解

每个组件对象都会有props(properties的简写)属性
组件标签的所有属性都保存在props中

2.3.2. 作用

通过标签属性从组件外向组件内传递变化的数据
注意: 组件内部不要修改props数据

2.3.3. 编码操作

1)内部读取某个属性值

this.props.propertyName

2)对props中的属性值进行类型限制和必要性限制

Person.propTypes = {
name: React.PropTypes.string.isRequired,
age: React.PropTypes.number.isRequired
}

3)扩展属性: 将对象的所有属性通过props传递

<Person {...person}/>

4)默认属性值

Person.defaultProps = {
name: 'Mary'
}

5)组件类的构造函数

constructor (props) {
super(props)
console.log(props) // 查看所有属性
}

2.3.4. 面试题

问题: 请区别一下组件的props和state属性

  • state: 组件自身内部可变化的数据
  • props: 从组件外部向组件内部传递数据, 组件内部只读不修改

2.4. 组件三大属性3: refs与事件处理

2.4.1. 组件的3大属性之二: refs属性

  • 组件内的标签都可以定义ref属性来标识自己
  1. <input type="text" ref={input => this.msgInput = input}/>
  2. 回调函数在组件初始化渲染完或卸载时自动调用
  • 在组件中可以通过this.msgInput来得到对应的真实DOM元素
  • 作用: 通过ref获取组件内容特定标签对象, 进行读取其相关数据

2.4.2. 事件处理

  • 通过onXxx属性指定组件的事件处理函数(注意大小写)
  1. React使用的是自定义(合成)事件, 而不是使用的原生DOM事件
  2. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)
  • 通过event.target得到发生事件的DOM元素对象
<input onFocus={this.handleClick}/>
handleFocus(event) {
event.target //返回input对象
}

2.4.3. 强烈注意

  • 组件内置的方法中的this为组件对象
  • 在组件类中自定义的方法中this为null
  1. 强制绑定this: 通过函数对象的bind()
  2. 箭头函数(ES6模块化编码时才能使用)

2.5. 组件的组合

2.5.1. 功能界面的组件化编码流程(无比重要)

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

2.6. 收集表单数据

2.6.1.. 理解

  • 问题: 在react应用中, 如何收集表单输入数据
  • 包含表单的组件分类
  1. 受控组件: 表单项输入数据能自动收集成状态
  2. 非受控组件: 需要时才手动读取表单输入框中的数据

2.7. 组件生命周期

2.7.1. 理解

  • 组件对象从创建到死亡它会经历特定的生命周期阶段
  • React组件对象包含一系列的勾子函数(生命周期回调函数), 在生命周期特定时刻回调
  • 我们在定义组件时, 可以重写特定的生命周期回调函数, 做特定的工作

2.7.2. 生命周期详述

  • 组件的三个生命周期状态:
  1.   * Mount:插入真实 DOM
  2.   * Update:被重新渲染
  3.   * Unmount:被移出真实 DOM
  • React 为每个状态都提供了勾子(hook)函数
  1.   * componentWillMount()
  2.   * componentDidMount()
  3.   * componentWillUpdate()
  4.   * componentDidUpdate()
  5.   * componentWillUnmount()

生命周期流程:

  • .第一次初始化渲染显示: ReactDOM.render()
  1.    * constructor(): 创建对象初始化state
  2.    * componentWillMount() : 将要插入回调
  3.    * render() : 用于插入虚拟DOM回调
  4.    * componentDidMount() : 已经插入回调
  • 每次更新state: this.setSate()
  1.    * componentWillUpdate() : 将要更新回调
  2.    * render() : 更新(重新渲染)
  3.    * componentDidUpdate() : 已经更新回调
  • 移除组件: ReactDOM.unmountComponentAtNode(containerDom)
  1.    * componentWillUnmount() : 组件将要被移除回调

2.7.3. 重要的勾子

  • render(): 初始化渲染或更新渲染调用
  • componentDidMount(): 开启监听, 发送ajax请求
  • componentWillUnmount(): 做一些收尾工作, 如: 清理定时器
  • componentWillReceiveProps(): props更新

第3章:react应用(基于react脚手架)

3.1. 使用create-react-app创建react应用

3.1.1. react脚手架

  • 1)xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
  1. 包含了所有需要的配置
  2. 指定好了所有的依赖
  3. 可以直接安装/编译/运行一个简单效果
  • 2)react提供了一个用于创建react项目的脚手架库: create-react-app
  • 3)项目的整体技术架构为: react + webpack + es6 + eslint
  • 4)使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

3.1.2. 创建项目并启动

npm install -g create-react-app
create-react-app hello-react
cd hello-react
npm start

3.1.3. react脚手架项目结构

ReactNews
	|--node_modules---第三方依赖模块文件夹
	|--public
		|-- index.html-----------------主页面
	|--scripts
		|-- build.js-------------------build打包引用配置
	|-- start.js-------------------start运行引用配置
	|--src------------源码文件夹
		|--components-----------------react组件
		|--index.js-------------------应用入口js
	|--.gitignore------git版本管制忽略的配置
	|--package.json----应用包配置文件 
	|--README.md-------应用描述说明的readme文件

第4章:react ajax

4.1. 理解

4.1.1. 前置说明

  • 1)React本身只关注于界面, 并不包含发送ajax请求的代码
  • 2)前端应用需要通过ajax请求与后台进行交互(json数据)
  • 3)react应用中需要集成第三方ajax库(或自己封装)

4.1.2. 常用的ajax请求库

  • 1)jQuery: 比较重, 如果需要另外引入不建议使用
  • 2)axios: 轻量级, 建议使用
  1. 封装XmlHttpRequest对象的ajax
  2. promise风格
  3. 可以用在浏览器端和node服务器端
  • fetch: 原生函数, 但老版本浏览器不支持
  1. 不再使用XmlHttpRequest对象提交ajax请求
  2. 为了兼容低版本的浏览器, 可以引入兼容库fetch.js

4.2. axios

4.2.1. 文档

https://github.com/axios/axios

4.2.2. 相关API

1)GET请求

axios.get('/user?ID=12345')
 .then(function (response) {
  console.log(response);
 })
 .catch(function (error) {
  console.log(error);
 });

axios.get('/user', {
  params: {
   ID: 12345
  }
 })
 .then(function (response) {
  console.log(response);
 })
 .catch(function (error) {
  console.log(error);
 });

2)POST请求

axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(function (response) {
 console.log(response);
})
.catch(function (error) {
 console.log(error);
});


4.3. Fetch

4.3.1. 文档

1)https://github.github.io/fetch/

2)https://segmentfault.com/a/1190000003810652

4.3.2. 相关API

1)GET请求

fetch(url).then(function(response) {
 return response.json()
}).then(function(data) {
 console.log(data)
}).catch(function(e) {
 console.log(e)
});


2)POST请求

fetch(url, {
 method: "POST",
 body: JSON.stringify(data),
}).then(function(data) {
 console.log(data)
}).catch(function(e) {
 console.log(e)
})