React

466 阅读13分钟

2-1 React简介

  1. 官网地址:reactjs.org
  2. react和vue比较 react 适合复杂度比较高的应用 vue 适合复杂度不高的应用(api 多)

2-2 React开发环境准备

create-react-app npm create-react-app my-app cd my-app npm start

2-3 工程目录文件简介 src/ index.js 入口文件 react设计理念 all in js

pwa progressive web application https协议的服务器上

registerServiceWorker 缓存

2-4 react中的组件

  1. 明白es6解构赋值

  2. import React,{ Component } from ‘react’

  3. import { Component } from ‘react’ 等价于 import React from ‘react’ const Component = React.Component

  4. ReactDOM是一个第三方模块,它有个方法render帮我们把组件app 挂载到页面的某个节点下

  5. 如果你在项目中用了jsx语法 你就一定要引用react,在react中 render函数中的标签也是jsx语法

index.js 是入口 app.js 是个组件

2-5 React 中最基础的JSX语法

  1. jsx自定义组件名以大写字母开头,不支持小写,小写为html标签

3-1 使用React编写TodoList功能

Fragment占位符 是一个组件

3-2 React 中的响应式设计思想和事件绑定

constructor 是最优先调用的函数 constructor(props){ super(props) } 继承固定写法

1.this.state 负责存储数据 2.jsx中js表达式用 { } 包裹 3.事件绑定需要通过bind(this)对函数的作用域进行变更 4.如果修改state中的内容,不能直接改,需要通过setState向里面传入对象的形式进行修改

3-3 实现 TodoList 新增删除功能

react中 事件名称首字母一定大写 例如: onClick, onChange ... 展开符 immutable 概念的意思 state 不允许我们做任何的改变,建议使用副本改变,否则会影响性能优化部分

3-4 JSX语法细节补充

1.注释

  1. { /comments/ }

2.{ // } 2.class改成className 2.dangerousluSetInnerHTML={{__html:Item}} 标签不转译 3.label用来扩大input框的点击范围,意思是当点label的时候,光标自动聚集在input中 label上写htmlFor input写id

3-5 拆分组件与组件之间的传值

1.父组件可以引用子组件,子组件还可以拆分子组件,这样往往形成一个树形结构。 2.父组件向子组件传值,通过属性的方法,既可以传值,也可以传递方法,然后在子组件的返回函数中通过this.props.属性值 来获取父组件传来的值

3-6 TodoList 代码优化

1.setState有个参数prevState 保存了数据改变之前的状态,相当于this.state 写法更靠谱性能更高

3-7 围绕 React 衍生出的思考

1.声明式开发 可减少大量的dom操作 jquery(命令式编程) 2.可以与其他框架并存 3.组件化 父组件通过属性向子组件传值,子组件想操作父组件怎么办呢?,首先通过父组件向子组件传递一个方法,子组件去调用这个方法, 间接的操作父组件的数据,子组件通过操作父组件方法从而改变父组件数据 ,从而实现父子组件间的传递

4.单项数据流 react中父组件可以向子组件传值,但是子组件不能改变父组件(方便维护代码)

5.视图型框架 小型项目可以只用react,但是在大型项目中只用react是不行的,因为当组件之间信息传递时,会出现很多冗余代码,只用react远远不够, 一般用它来搭建视图,在做组件传值时要引入一些框架(React只解决页面和数据的渲染问题);

6.函数式编程

1.易维护,可拆分 2.用react做出来的项目更容易作前端的自动化测试

4-1 React developer tools 安装及使用 翻墙安装就行 蓝灯翻墙工具

4-2 PropTypes 与 DefaultProps 的应用

import PropTypes from 'prop-types'

PropTypes 属性校验 DefaultProps 默认属性

4-3 props,state 与 render 函数的关系

  1. 当组件的state或者props发生改变的时候,render函数就会重新执行
  2. 当父组件的render函数被运行时,它的子组件的render都将被重新运行

4-4 React 中的虚拟DOM 1 state 数据 2 jsx 模板 3 数据 + 模板 结合,生成真实的dom,来显示 4 state 发生改变 5 数据 + 模板 结合,生成真实的Dom,并不直接替换原始的Dom 6 新的dom 和原始的dom 做比较,找差异 7 找出input框发生的变化 8 只用新的dom中的input元素,替换掉老的dom中的input元素 性能提升不明显

缺陷: 第一次生成了一个完整的DOm片段 第二次生成了一个完整的DOM片段

1 state 数据 2 jsx 模板 3 生成虚拟Dom (虚拟dom就是一个js对象,用它来描述真实的dom) 4 用虚拟dom的结构

生成真实的dom,来显示 5 state 发生变化 6 数据+模板 生成新的虚拟dom

7 比较原始的虚拟dom和新的虚拟dom的区别,找出区别是span中的内容 8 直接操作dom 改变span中的内容

react中减少了dom的创建和对比 本

质上就是js操作对象比js操作dom性能要小的多 react中的虚拟dom其实是一个js

对象,创建一个js对象很简

单,不会消耗太多的性

4-5 深入了解虚拟DOM

jsx--------------> js对象->真实dom createElement

优点 1.性能提升了 2.它使得跨端应用得以实现(原生应用里没有真实DOM,而是一些原生组件) React Native

4-6 虚拟dom中的Diff算法 1.setState 是异步的 为了提升react底层性能,它可以把三次的setSate结合成一次的setState 2. react虚拟dom同级比对 3. 虚拟dom的循环的时候,需要给它指定唯一稳定的key,保证在虚拟dom对比的高效,不推荐使用索引作为key,不稳定

同级比对好处 1.算法简单 速度快

react的diff算法:

  1. 同级比较,如果第一级有差异的话,就不会比较下面级别了,直接替换当前级别往下的所有级别;
  2. 虚拟dom的循环的时候,需要给它指定唯一稳定的key,保证在虚拟dom对比的高效,不推荐使用索引作为key,不稳定;
  3. 当调用setState的时候,才会运行diff算法进行数据比对,从而重新渲染;setState 设计成异步模式的初衷,提高底层的渲染性能,比如连续三次调用setState,只会渲染最后一次的setState;

4-7 React中ref的使用

1.ref={(input)=>{this.input = input}} 2.ref是react中获取DOM节点的方法,尽量不使用(除了复杂的操作) ,如果使用的话最好放在setState(()=>(),()=>{})第二个回调函数内

4-8 React的生命周期函数

定义:生命周期函数指组件在某一时刻会自动调用执行的函数 组件挂载流程 组件第一次挂载的时候 1.componentWillMount //在组件即将被挂载到页面的时刻自动执行 2.render 2.componentDidMount //在组件挂载后自动执行 组件更新流程 props更新 1.componentWillReceiveProps 当一个组件要从父组件接受参数 如果这个组件第一次存在于父组件中,不执行 如果这个组件之前就存在于父组件中,才会执行

states更新 1.shouldComponentUpdate 组件被更新之前,自动执行,但是要求返回布尔值结果 2.componentWillUpdate 组件被更新之前,它会自动执行,但是他在shouldComponentUpdate之后执行 如果shuldComponentUpdate返回true它才执行 如果返回false,这个函数就不会被执行了 3.render 4.componentDidMount 数据更新完调用

组件卸载 componentWillUnmount 当这个组件即将被页面剔除的时候,会执行

生命周期变化(重点) 1.首先页面初始化,constructor里面去做一些props和state的设置 2.组件要被挂载到页面上,在挂载的时候会自动执行三个周期函数(componentWillMount,render,compontentDidmount) 3.当组件发生变化时,数据发生变化页面就会发生变化,一些周期函数就会被调用 首先调用 shouldComponentWillUpdate 如果他返回false,就到此为止不往下执行了, 如果返回true,就会向下执行componentWillUpdate,render,componentDidUpdate 4.假设一个组件从父组件接受props参数,当父组件重新渲染的时候,子组件的componentWillReceiveProps会被执行 接下来子组件就会再执行一下第三步骤 5.当一个组件要被移除的时候 componentWillUnmount生命周期函数 会被自动执行

注意:生命周期函数是对于一个组件来说的,而不是对父组件来说的

4-9 react生命周期的使用场景

React性能优化 react可以提升代码的点(重点) 1.把作用域的修改放在constructor里面,可以保证整个作用域里面这个函数的绑定只会执行一次,而且可以避免子组件的一些无谓的渲染 2.setState,React内置函数的提升,是一个异步函数,可以把数据的多次改变结合成一次,降低虚拟dom的比对频率 3.react底层虚拟dom概念,同级比对,key值概念,加快比对速度,从而提升react性能 4.借助shouldComponentUpdata这个周期函数,可以避免组件无谓的render函数的渲染

注意:ajax 放在 componentDidMount 周期函数中最合适

4-10 使用Charles 实现本地数据mock

学会使用Charles

5-1 Redux 概念简述

1.redux = reducer + flux

2.Redux的设计理念(重点):把所有的数据放到store里进行管理,一个组件改变的store里面的内容, 其他的组件就感知到了store里面的变化,再来取数据,从而间接的实现了组件之间实现数据传递的功能。

5-2 Redux的工作流程

redux是视图层框架,把所有数据都放在store之中,每个组件都要从store里拿数据,然后每个组件也要去改store里面的数据, 举例:把这个流程理解成一个图书馆的流程 react compontents:借书的人 action creators:“要借什么书”这句话(语句的表达,数据的传递) store:图书馆管理员(没办法记住所有书籍的存储情况) reducers:图书馆管理员的记录本(要借什么书,先查有没有,要还的书查一下放到某个位置); 借书的人~我要借一本书~图书管理员听见~查阅reducers手册~去store找书~把对应的书给借书人;

5-3 使用Antd实现TodoList页面布局

1.yarn add antd 2.npm install antd --save ant.design/docs/react/…

5-4 创建redux yarn add redux

  1. store/index.js

import { createStore } form ‘redux’ improt reducer from ‘./reducer’ const stroe = createStore(reducer)

export default store

  1. store/reducer.js const defaultState = {} export default (state = defaultState, action) => {

return state; } state 指的就是数据 reducer返回的必须是个纯函数

5-5 Action 和 Reducer

1.reduer 可以接受state,但是绝不能修改state redux流程(重点)

1 react首先要改变stroe里的数据,先要派发一个action, action通过dispatch(action)方法传给store 2 stroe 把之前的数据和action(previousState,action)传个reducer 3 reducer是个函数,它接收了state和action以后做些处理会返回一个新的newState给到store 4 stroe用这个新的state替换到原来的数据,stroe数据改变了以后,react组件感受到了数据变化,它会从 store里面重新取数据,更新组件的内容,页面就会跟着发生变化了

2.关于深拷贝和浅拷贝-----:浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。 但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

5-7 ActionTypes的拆分

为什么要对ActionTypes进行拆分? 答:如果常量或变量在代码里写错的时候,是会报出异常的,就可以迅速定位到问题, 但是如果写一个字符串的话就不会报出异常,那样的话出了bug非常难调,所以才要进行ActionTypes的拆分

5-8 使用actionCreator统一创建action

原因.提高代码的可维护性,把action都写在一个文件里面的话做自动化测试也会非常方便

store文件夹里面包含的文件 store / actionCreators.js actionTypes.js index.js reducer.js

5-9 Redux 知识点补充 redux设计和使用的三项原则(重点) 三项原则 1.store是唯一的 2.只有store能够改变自己的内容 3.reducer是个纯函数 纯函数: 是指给固定的输入,就会一定会有固定的输出,而且不会有任何副作用 不能有跟时间相关的操作,对参数的修改就是副作用

Redux 核心的API 1、createStore (创建store) 2、store.disptch (派发action,action会传递给store) 3、store.getState (获取store,里面所有数据内容) 4、store.subscribe (订阅store的改变,只要store,发生改变,store.subscribe 接受的回调函数就会被执行)

6-1 UI组件和容器组件

UI组件负责页面的渲染,容器组件负责页面的逻辑。

6-2 无状态组件

  1. 当一个组件只有render函数时,可以用无状态组件代替
  2. 无状态组件性能比较高,没有生命周期函数,其实无状态组件就是一个函数

const a= (props) => { return () }

6-1 Redux 中发送异步请求获取数据

1.window安装: npm install axios --save 2.安装Charles

6-4 使用Redux-thunk 中间件实现ajax数据请求

  1. github.com/zalmoxisus/…

2.redux-thunk: 可以把异步操作的代码移除到actionCreators中,原本actionCreators中任何一个action都是一个函数返回的是一个对象, 用了Redux-thunk以后可以返回一个函数了

3.当action返回是一个函数时,这个函数能够接收到store的dispatch方法 npm install --save redux-thunk redux-thunk优点: 方便维护,有利于于自动化测试

6-5 什么是rudex中间件?

1.中间件是指在action和Stroe中间的dispatch方法的一个封装和升级,原本action只返回一个对象,使用中间件之后可以返回一个函数 2. dispatch自动分辨接收的参数是对象还是函数,如果参数是个对象,dispatch方法会直接把参数传给store, 如果参数是一个函数,那么dispatch等这个函数执行完以后再传给store

比较火的redux中间件:redux-saga redux-thunk redux-logger

6-6——6-7 Redux-saga中间件的使用 generetor函数 按照官网配置Redux-saga:github.com/redux-saga/… redux-saga使用流程

  1. store/index.js 首先创建store的时候根据官网配置好 首先引入createSagaMiddleware import createSagaMiddleware from 'redux-saga' 然后创建一个sagaMiddleware const sagaMiddleware = createSagaMiddleware() 通过applyMiddleware使用 applyMiddleware(sagaMiddleware) 创建文件store/sagas.js 在store/index.js 中引入 import mySaga from './sagas' 运行sagas.js sagaMiddleware.run(mySaga)
  2. sagas.js sagas文件中一定要导出generator函数,这个函数里面的意思就是当接受到get_init_list类型的action时, 就会调用getInitList()这个generator函数,它会去取数据,取完数据后会再派发一个action传给store, store把action给了reduer,reducer处理返回的数据给store

6-8 如何使用 React-redux(1) provider : 是react-redux第一个核心api,意思是链接store,那么被它包裹的组件就都可以获取store里面的内容了

connet:是react-redux第二个核心api,链接组件和store