React全量知识点

1,154 阅读14分钟

React基础

 官网

1) 英文官网: https://reactjs.org/

2) 中文官网: doc.react-china.org/

介绍描述

1) 用于构建用户界面的 JavaScript 库(只关注于View)

2) 由Facebook开源

 React的特点

1) Declarative(声明式编码)

2) Component-Based(组件化编码)

3) Learn Once, Write Anywhere(支持客户端与服务器渲染)

4) 高效

5) 单向数据流

 React高效的原因

1) 虚拟(virtual)DOM, 不总是直接操作DOM

2) DOM Diff算法, 最小化页面重绘

 React的基本使用

注意: 此时只是测试语法使用, 并不是真实项目开发使用

 效果

image.png

 相关js库

1) react.js: React的核心库

2) react-dom.js: 提供操作DOM的react扩展库

3) babel.min.js: 解析JSX语法代码转为纯JS语法代码的库

 在页面中导入js

image.png

 编码

 <**script** **type=** **"text/babel"** >  
 *//* *必须声明* *babel** **//* 
 *创建虚拟* *DOM* *元素** ***
 **const** ***vDom*** = <**h1**>Hello React</**h1**>  
 *//* *千万不要加引号*    
 *//* *渲染虚拟* *DOM* *到页面真实* *DOM* *容器中** *****ReactDOM**.render(***vDom***, **document**.getElementById( **'test'** )) </**script**> 

 虚拟DOM

1) React提供了一些API来创建一种 特别 的一般js对象

a. var element = React.createElement('h1', {id:'myTitle'},'hello')

b. 上面创建的就是一个简单的虚拟DOM对象

2) 虚拟DOM对象最终都会被React转换为真实的DOM

3) 我们编码时基本只需要操作react的虚拟DOM相关数据, react会转换为真实DOM变化而更新界面

 JSX

1) 全称:  JavaScript XML

2) react定义的一种类似于XML的JS扩展语法: XML+JS

3) 作用: 用来创建react虚拟DOM(元素)对象

var ele = <h1>Hello JSX!</h1>

b. 注意1: 它不是字符串, 也不是HTML/XML标签

c. 注意2: 它最终产生的就是一个JS对象

4) 标签名任意: HTML标签或其它标签

5) 标签属性任意: HTML标签属性或其它

6) 基本语法规则

a. 遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析

b. 遇到以 { 开头的代码,以JS语法解析: 标签中的js代码必须用{ }包含

7) babel.js的作用

a. 浏览器不能直接解析JSX代码, 需要babel转译为纯JS的代码才能运行

b. 只要用了JSX,都要加上type="text/babel", 声明需要babel来处理

React面向组件编程

自定义组件

image.png

注意

1) 组件名必须首字母大写

2) 虚拟DOM元素只能有一个根元素

3) 虚拟DOM元素必须有结束标签

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

1) React内部会创建组件实例对象

2) 得到包含的虚拟DOM并解析为真实DOM

3) 插入到指定的页面元素内部

组件三大属性1: state

1) state是组件对象最重要的属性, 值是对象(可以包含多个数据)

2) 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

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

this.setState({
stateProp1 : value1,
})

组件三大属性2: props

1) 通过标签属性从组件外向组件内传递变化的数据

2) 注意: 组件内部不要修改props数据


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) // 查看所有属性

}

refs与事件处理

1) 组件内的标签都可以定义ref属性来标识自己

a. <input type="text" ref={input => this.msgInput = input}/>

b. 回调函数在组件初始化渲染完或卸载时自动调用

2) 在组件中可以通过this.msgInput来得到对应的真实DOM元素

3) 作用: 通过ref获取组件内容特定标签对象, 进行读取其相关数据

事件处理

1) 通过onXxx属性指定组件的事件处理函数(注意大小写)

a. React使用的是自定义(合成)事件, 而不是使用的原生DOM事件

b. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)

2) 通过event.target得到发生事件的DOM元素对象


*handleFocus(event) {***

*event.target  //返回input对象***

}

注意

1) 组件内置的方法中的this为组件对象

2) 在组件类中自定义的方法中this为null

a. 强制绑定this: 通过函数对象的bind()

b. 箭头函数(ES6模块化编码时才能使用)

受控组件和不受控组件的使用场景

受控组件

在 HTML 中,表单元素(如<input>、 <textarea> 和 <select>)通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新。

我们可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。

非受控组件

非受控组件,而不是为每个状态更新都编写数据处理函数,你可以 使用 ref 来从 DOM 节点中获取表单数据

ref定义:
<input type="text" ref={this.input} />

this.input = React.createRef();  

使用:
handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
}

如果您的表单在UI反馈方面非常简单,则不受 refs 控制完全没问题。

image.png

包含表单的组件分类

  • 受控组件: 表单项输入数据能自动收集成状态
  • 非受控组件: 需要时才手动读取表单输入框中的数据

生命周期流程图

image.png

虚拟DOM与DOM Diff算法

image.png

react ajax

1) jQuery: 比较重, 如果需要另外引入不建议使用

2) axios: 轻量级, 建议使用

a. 封装XmlHttpRequest对象的ajax

b.  promise风格

c. 可以用在浏览器端和node服务器端

3) fetch: 原生函数, 但老版本浏览器不支持

a. 不再使用XmlHttpRequest对象提交ajax请求

b. 为了兼容低版本的浏览器, 可以引入兼容库fetch.js

axios

1GET请求

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);  });  
 

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

组件间通信

方式一: 通过props传递****

1) 共同的数据放在父组件上, 特有的数据放在自己组件内部(state)

2) 通过props可以传递一般数据和函数数据, 只能一层一层传递

3) 一般数据-->父组件传递数据给子组件-->子组件读取数据

4) 函数数据-->子组件传递数据给父组件-->子组件调用函数

方式二: 使用消息订阅(subscribe)-发布(publish)机制****

1) 工具库: PubSubJS

2) 下载: npm install pubsub-js --save

3) 使用:

  import PubSub from 'pubsub-js' //引入

  PubSub.subscribe('delete', function(data){ }); //订阅

  PubSub.publish('delete', data) //发布消息


learn_from_bili_goToGuigu## 1.1. React的基本认识

 官网

1) 英文官网: https://reactjs.org/

2) 中文官网: doc.react-china.org/

介绍描述

1) 用于构建用户界面的 JavaScript 库(只关注于View)

2) 由Facebook开源

 React的特点

1) Declarative(声明式编码)

2) Component-Based(组件化编码)

3) Learn Once, Write Anywhere(支持客户端与服务器渲染)

4) 高效

5) 单向数据流

 React高效的原因

1) 虚拟(virtual)DOM, 不总是直接操作DOM

2) DOM Diff算法, 最小化页面重绘

 React的基本使用

注意: 此时只是测试语法使用, 并不是真实项目开发使用

 效果

image.png

 相关js库

1) react.js: React的核心库

2) react-dom.js: 提供操作DOM的react扩展库

3) babel.min.js: 解析JSX语法代码转为纯JS语法代码的库

 在页面中导入js

image.png

 编码

 <**script** **type=** **"text/babel"** >  
 *//* *必须声明* *babel** **//* 
 *创建虚拟* *DOM* *元素** ***
 **const** ***vDom*** = <**h1**>Hello React</**h1**>  
 *//* *千万不要加引号*    
 *//* *渲染虚拟* *DOM* *到页面真实* *DOM* *容器中** *****ReactDOM**.render(***vDom***, **document**.getElementById( **'test'** )) </**script**> 

 虚拟DOM

1) React提供了一些API来创建一种 特别 的一般js对象

a. var element = React.createElement('h1', {id:'myTitle'},'hello')

b. 上面创建的就是一个简单的虚拟DOM对象

2) 虚拟DOM对象最终都会被React转换为真实的DOM

3) 我们编码时基本只需要操作react的虚拟DOM相关数据, react会转换为真实DOM变化而更新界面

 JSX

1) 全称:  JavaScript XML

2) react定义的一种类似于XML的JS扩展语法: XML+JS

3) 作用: 用来创建react虚拟DOM(元素)对象

var ele = <h1>Hello JSX!</h1>

b. 注意1: 它不是字符串, 也不是HTML/XML标签

c. 注意2: 它最终产生的就是一个JS对象

4) 标签名任意: HTML标签或其它标签

5) 标签属性任意: HTML标签属性或其它

6) 基本语法规则

a. 遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析

b. 遇到以 { 开头的代码,以JS语法解析: 标签中的js代码必须用{ }包含

7) babel.js的作用

a. 浏览器不能直接解析JSX代码, 需要babel转译为纯JS的代码才能运行

b. 只要用了JSX,都要加上type="text/babel", 声明需要babel来处理

React面向组件编程

自定义组件

image.png

注意

1) 组件名必须首字母大写

2) 虚拟DOM元素只能有一个根元素

3) 虚拟DOM元素必须有结束标签

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

1) React内部会创建组件实例对象

2) 得到包含的虚拟DOM并解析为真实DOM

3) 插入到指定的页面元素内部

组件三大属性1: state

1) state是组件对象最重要的属性, 值是对象(可以包含多个数据)

2) 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

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

this.setState({
stateProp1 : value1,
})

组件三大属性2: props

1) 通过标签属性从组件外向组件内传递变化的数据

2) 注意: 组件内部不要修改props数据


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) // 查看所有属性

}

refs与事件处理

1) 组件内的标签都可以定义ref属性来标识自己

a. <input type="text" ref={input => this.msgInput = input}/>

b. 回调函数在组件初始化渲染完或卸载时自动调用

2) 在组件中可以通过this.msgInput来得到对应的真实DOM元素

3) 作用: 通过ref获取组件内容特定标签对象, 进行读取其相关数据

事件处理

1) 通过onXxx属性指定组件的事件处理函数(注意大小写)

a. React使用的是自定义(合成)事件, 而不是使用的原生DOM事件

b. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)

2) 通过event.target得到发生事件的DOM元素对象


*handleFocus(event) {***

*event.target  //返回input对象***

}

注意

1) 组件内置的方法中的this为组件对象

2) 在组件类中自定义的方法中this为null

a. 强制绑定this: 通过函数对象的bind()

b. 箭头函数(ES6模块化编码时才能使用)

受控组件和不受控组件的使用场景

受控组件

在 HTML 中,表单元素(如<input>、 <textarea> 和 <select>)通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新。

我们可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。

非受控组件

非受控组件,而不是为每个状态更新都编写数据处理函数,你可以 使用 ref 来从 DOM 节点中获取表单数据

ref定义:
<input type="text" ref={this.input} />

this.input = React.createRef();  

使用:
handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
}

如果您的表单在UI反馈方面非常简单,则不受 refs 控制完全没问题。

image.png

包含表单的组件分类

  • 受控组件: 表单项输入数据能自动收集成状态
  • 非受控组件: 需要时才手动读取表单输入框中的数据

生命周期流程图

image.png

虚拟DOM与DOM Diff算法

image.png

react ajax

1) jQuery: 比较重, 如果需要另外引入不建议使用

2) axios: 轻量级, 建议使用

a. 封装XmlHttpRequest对象的ajax

b.  promise风格

c. 可以用在浏览器端和node服务器端

3) fetch: 原生函数, 但老版本浏览器不支持

a. 不再使用XmlHttpRequest对象提交ajax请求

b. 为了兼容低版本的浏览器, 可以引入兼容库fetch.js

axios

1GET请求

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);  });  
 

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

组件间通信

方式一: 通过props传递****

1) 共同的数据放在父组件上, 特有的数据放在自己组件内部(state)

2) 通过props可以传递一般数据和函数数据, 只能一层一层传递

3) 一般数据-->父组件传递数据给子组件-->子组件读取数据

4) 函数数据-->子组件传递数据给父组件-->子组件调用函数

方式二: 使用消息订阅(subscribe)-发布(publish)机制****

1) 工具库: PubSubJS

2) 下载: npm install pubsub-js --save

3) 使用:

  import PubSub from 'pubsub-js' //引入

  PubSub.subscribe('delete', function(data){ }); //订阅

  PubSub.publish('delete', data) //发布消息

ES6常用新语法

1) 定义常量/变量:  const/let

2) 解构赋值: let {a, b} = this.props   import {aa} from 'xxx'

3) 对象的简洁表达: {a, b}

4) 箭头函数:

a. 常用场景

  • 组件的自定义方法: xxx = () => {}

  • 参数匿名函数

b. 优点:

  • 简洁

  • 没有自己的this,使用引用this查找的是外部this

5) 扩展(三点)运算符: 拆解对象(const MyProps = {}, <Xxx {...MyProps}>)

6) 类:  class/extends/constructor/super

7) ES6模块化:  export default | import

react-router4.0

1) react的一个插件库

2)  专门用来实现一个SPA应用

3)  基于react的项目基本都会用到此库

SPA的理解*

1) 单页Web应用(single page web application,SPA)

2)  整个应用只有一个完整的页面

3)  点击页面中的链接不会刷新页面, 本身也不会向服务器发请求

4)  当点击路由链接时, 只会做页面的局部更新

5)  数据都需要通过ajax请求获取, 并在前端异步展现

路由的理解*

1) 什么是路由?

a. 一个路由就是一个映射关系(key:value)

b. key为路由路径, value可能是function/component

2) 路由分类

a. 后台路由: node服务器端路由, value是function, 用来处理客户端提交的请求并返回一个响应数据

b. 前台路由: 浏览器端路由, value是component, 当请求的是路由path时, 浏览器端前没有发送http请求, 但界面会更新显示对应的组件

3) 后台路由

a. 注册路由: router.get(path, function(req, res))

b. 当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据

4)  前端路由

a. 注册路由:

b. 当浏览器的hash变为#about时, 当前路由组件就会变为About组件

前端路由的实现

1) history库


a. 网址: <https://github.com/ReactTraining/history>

b. 管理浏览器会话历史(history)的工具库

c. 包装的是原生BOMwindow.historywindow.location.hash

2) history API

a. History.createBrowserHistory(): 得到封装window.history的管理对象

b. History.createHashHistory(): 得到封装window.location.hash的管理对象

c. history.push(): 添加一个新的历史记录

d. history.replace(): 用一个新的历史记录替换当前的记录

e. history.goBack(): 回退到上一个历史记录

f. history.goForword(): 前进到下一个历史记录

g. history.listen(function(location){}): 监视历史记录的变化

redux### 学习文档****

1) 英文文档: redux.js.org/

2) 中文文档: www.redux.org.cn/

3) Github: github.com/reactjs/red…

redux是什么?

1) redux是一个独立专门用于做状态管理的JS库(不是react插件库)

2) 它可以用在react, angular, vue等项目中, 但基本与react配合使用

3) 作用: 集中式管理react应用中多个组件共享的状态

redux工作流程

image.png

什么情况下需要使用redux

1) 总体原则: 能不用就不用, 如果不用比较吃力才考虑使用

2)  某个组件的状态,需要共享

3)  某个状态需要在任何地方都可以拿到

4)  一个组件需要改变全局状态

5)  一个组件需要改变另一个组件的状态

redux的核心API

createStore()

1) 作用:

创建包含指定reducer的store对象

2) 编码:

import {createStore} from 'redux'

import counter from './reducers/counter'

const store = createStore(counter)

store对象

1) 作用:

redux库最核心的管理对象

2) 它内部维护着:

state

reducer

3) 核心方法:

getState()

dispatch(action)

subscribe(listener)

4) 编码:

store.getState()

store.dispatch({type:'INCREMENT', number})

store.subscribe(render)

applyMiddleware()******

1) 作用:

应用上基于redux的中间件(插件库)

2) 编码:

import {createStore, applyMiddleware} from 'redux'

import thunk from 'redux-thunk'  // redux异步中间件

const store = createStore(

  counter,

  applyMiddleware(thunk) // 应用上异步中间件

)

combineReducers()******

1) 作用:

合并多个reducer函数

2) 编码:

export default combineReducers({

  user,

  chatUser,

  chat

})

redux的三个核心概念

action

1) 标识要执行行为的对象

2) 包含2个方面的属性

a. type: 标识属性, 值为字符串, 唯一, 必要属性

b. xxx: 数据属性, 值类型任意, 可选属性

3) 例子:

const action = {

type: 'INCREMENT',

data: 2

}

4) Action Creator(创建Action的工厂函数)

const increment = (number) => ({type: 'INCREMENT', data: number})

reducer

1) 根据老的state和action, 产生新的state的纯函数

2) 样例

export default function counter(state = 0, action) {

  switch (action.type) {

    case 'INCREMENT':

      return state + action.data

    case 'DECREMENT':

      return state - action.data

    default:

      return state

  }

}

3) 注意

a. 返回一个新的状态

b. 不要修改原来的状态

store

1) 将state,action与reducer联系在一起的对象

2) 如何得到此对象?

import {createStore} from 'redux'

import reducer from './reducers'

const store = createStore(reducer)

3) 此对象的功能?

getState(): 得到state

dispatch(action): 分发action, 触发reducer调用, 产生新的state

subscribe(listener): 注册监听, 当产生了新的state时, 自动调用

纯函数和高阶函数

纯函数

1) 一类特别的函数: 只要是同样的输入,必定得到同样的输出

2) 必须遵守以下一些约束  

a. 不得改写参数

b. 不能调用系统 I/O 的API

c. 能调用Date.now()或者Math.random()等不纯的方法  

3) reducer函数必须是一个纯函数

高阶函数

4) 理解: 一类特别的函数

a. 情况1: 参数是函数

b. 情况2: 返回是函数

5)  常见的高阶函数:

a. 定时器设置函数

b. 数组的map()/filter()/reduce()/find()/bind()

c. react-redux中的connect函数

6)  作用:

a. 能实现更加动态, 更加可扩展的功能


reference_goToGuigu