(1)webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。Webpack是一个前端模块化方案,更侧重模块打包。
我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源.Webpack就是需要通过其配置文件(Webpack.config.js)中 entry 配置的一个入口文件(JS文件),然后在解析过程中,发现其他的模块,如scss等文件,再调用配置的loader或者插件对相关文件进行解析处理。
(2)grunt/gulp的核心是Task ,我们可以配置一系列的task,并且定义task要处理的事务(例如ES6、ts转化,图片压缩,scss转成css) 之后让grunt/gulp来依次执行这些task,而且让整个流程自动化。所以grunt/gulp也被称为前端自动化任务管理工具。
如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。只需要进行简单的合并、压缩,就使用grunt/gulp即可。grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
(3)Git,免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
1. 直接记录快照,而非差异比较
git 关心的只是文件数据的整体是否发生变化,而大多数其他系统(比如svn)则只关心文件内容的具体差异,每次记录都有哪些文件做了更新,以及都更新了哪些行的什么内容。
2.近乎所有操作都是本地执行
在git中的绝大多数操作都只需要访问本地文件和资源,不用联网,因为它有本地数据库的镜像。但如果用集中式版本控制系统的话,差不多所有操作都需要联网,因为git 在本地磁盘上就保存着所有当前项目的历史更新,所以处理起来速度飞快。
3.时刻保持数据完整性
在保存到git 之前,所有数据都要进行内容的校验和计算,并将此结果作为数据的唯一标识和索引。换句话说,不可能在你修改了文件或目录之后,git 一无所知。这项特性作为git 的设计哲学,建在整体架构的最底层。所以如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,git都能立即察觉。
初始化package.json |
npm init -y |
安装webpack依赖 |
npm install webpack --save-dev npm info webpack : 查看webpack 信息 npm install [email protected] --save-dev : 安装指定版本的 webpack |
安装webpack开发工具 |
npm install webpack-dev-server --save-dev npm install webpack-dev-server -g |
安装css loader |
npm install css-loader style-loader |
编译显示进度和颜色 |
webpack --progress --colors webpack --progress --colors --watch |
快速编译,热更新 |
webpack --progress --colors --watch webpack-dev-server --progress --colors :使用开发包 |
安装加载url-loader |
npm install url-loader --save-dev |
缩写 |
--save-dev : 保存到 package.json 的 devDependencies 依赖中缩写:-D --save : 保存到 package.json 的 dependencies 依赖中 缩写 : -S |
压缩混淆脚本 |
webpack -p //压缩混淆脚本,这个非常非常重要! |
生成map映射文件 |
webpack -d //生成map映射文件,告知哪些模块被最终打包到哪里了其中的 |
全局安装 |
npm install webpack -g |
开发环境:开发人员调试开发的一种环境,方便调试,保持高效的开发。
生产环境:发布上线的环境,让程序在生产环境中正常有效的运行。
在项目开发的时候,我们通常会将程序分为开发环境和生产环境(或者叫线上环境),开发环境通常指的是我们正在开发的这个阶段所需要的一些环境配置,也就是方便我们开发人员调试开发的一种环境;生产环境通常指的是我们将程序开发完成经过测试之后无明显异常准备发布上线的环境,也可以理解为用户可以正常使用的就是生产环境;
开发环境的需求:
模块热更新 (本地开启服务,实时更新)
sourceMap (代码映射,方便打包调试)
接口代理 (配置proxyTable解决开发环境中的跨域问题)
代码规范检查 (代码规范检查工具)
生产环境的需求:
提取公共代码
压缩混淆(压缩混淆代码,清除代码空格,注释等信息使其变得难以阅读)
文件压缩/base64编码(压缩代码,减少线上环境文件包的大小)
去除无用的代码
开发环境和生产环境的共同需求:
入口
代码处理(loader处理)
解析配置
运行环境:npm start
优点
组件更加清晰直观
组件关系更加清晰
结果可以预测
优越
最小化了重绘(diff算法)
避免了不必要的dom操作
什么是组件和模块?
组件
把重复的代码提取出来合并成为一个个组件,组件最重要的就是重用(复用),位于框架最底层,其他功能都依赖于组件,可供不同功能使用,独立性强。
模块
分属同一功能/业务的代码进行隔离(分装)成独立的模块,可以独立运行,以页面、功能或其他不同粒度划分程度不同的模块,位于业务框架层,模块间通过接口调用,目的是降低模块间的耦合,由之前的主应用与模块耦合,变为主应用与接口耦合,接口与模块耦合。模块就像有多个USB插口的充电宝,可以和多部手机充电,接口可以随意插拔。复用性很强,可以独立管理。
组件和模块的区别
组件就像一个个小的单位,多个组件可以组合成组件库,方便调用和复用,组件间也可以嵌套,小组件组合成大组件。
模块就像是独立的功能和项目(如淘宝:注册、登录、购物、直播…),可以调用组件来组成模块,多个模块可以组合成业务框架。
为什么要使用组件化和模块化?
1 开发和调试效率高
随着功能越来越多,代码结构会越发复杂,要修改某一个小功能,可能要重新翻阅整个项目的代码,把所有相同的地方都修改一遍,重复劳动浪费时间和人力,效率低;使用组件化,每个相同的功能结构都调用同一个组件,只需要修改这个组件,即可全局修改。
2 可维护性强
便于后期代码查找和维护。
3 避免阻断
模块化是可以独立运行的,如果一个模块产生了bug,不会影响其他模块的调用。便于后期代码查找和维护。
4 版本管理更容易
如果由多人协作开发,可以避免代码覆盖和冲突。
组件化和模块化一般情况是一起出现的,他们就像好兄弟,虽然可以分离但最好一起有个照应。
(1)react是一个用于创建可复用、可聚合的web组件库.
(2)react提供的只是mvc里面的c部门,不是全部的mvc框架.
特点:
(1)组件化:不是一大堆html代码模板.
(2)js逻辑与html标签紧密连接.
(3)单向数据传输.
(4)虚拟的DOM结构.
3.优点
(1)组件更加清晰直观.
(2)组件关系更加清晰.
(3)结果可以预测.
1.MVC是一种使用MVC(Model View Controller 模型-视图-控制器)设计创建Web应用程序的模式.
(1)Model(模型)表示应用程序核心(比如数据库记录列表).
(2)View(视图)显示数据(数据库记录).
(3)Controller(控制器)处理输入(写入数据库记录).
2.MVC模式同时提供了对HTML、CSS和JavaScript的完全控制.
(1)Model(模式)是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据.
(2)View(视图)是应用程序中出处理数据显示的部分,通常视图是依据模型数据创建的.
(3)Controller(控制器)是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据.
MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。
View层是视图层,也就是用户界面。前端主要由HTML和CSS来构建;
Model层 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,对于前端来说就是后端的提供的API接口;
ViewModel层是视图数据层,一个同步View和Model的对象。
在MVVM架构下,View和Model之间并没有直接的联系,而是通过ViewModel进行交互,Model和ViewModel之间的交互是双向的,因此View数据的变化会同步到Model中,而Model数据的变化也会立即反应到View上。
ViewModel通过双向数据绑定把View层和Model层连接了起来,而View和Model之间的同步工作完全是自动的,无需人为干涉,因此开发者只需要关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。
Jsx:
可以在js中使用javascript 表达式。表达式写在花括号{}中
Jsx中不能使用 if else语句,但可以使用三元运算符表达式来代替 ?:
React推荐使用内联样式(行内样式)。我们可以使用驼峰法语法来设置内联样式
react会在指定元素数字后自动添加px 注释需要写在花括号中
Jsx允许在模板中插入数组,数组会自动展开所有成员
React可以渲染HTML标签(strings)或react组件(classes)
要渲染HTML标签,只需在jsx里使用小写字母的标签名
需要渲染react组件,只需要创建一个大写字母开头的本地变量
1.jsx是一个看起来很像XML的JavaScript语法扩展,React可以用来做简单的JSX句法转换.
2.为什么要使用JSX?
(1)你不需要为了React使用JSX,可以直接使用纯粹的JS,但我们更建议使用JSX,因为它能定义简洁且我们熟知的包含属性的树状结构语句.
(2)对于非专职开发者(比如设计师)同样比较熟悉.
(3)XML有固定的标签开启和闭合,这能让复杂的树更易于阅读,由于方法调用和对象字面量的形式.
(4)它没有修改JavaScript语义.
3.JSX的语法,它允许HTML与JavaScript的混写.
4.jsx遇到HTML标签(以 < 开头),就用HTML规则解析,遇到代码块(以 { 开头),就用JavaScript规则解析.
5.ReactDOM.render():是React的最基本方法,用于将模板转为HTML语言,并插入指定的DOM节点.
6.JavaScript表达式的使用:
(1)可以在JSX 中使用JavaScript表达式,表达式写在花括号 { } 中.
ReactDOM.render(
document.getElementById('example'));
(2)在JSX中不能使用if else 语句,但可以使用conditional(三元运算)表达式来替代:
ReactDOM.render(
document.getElementById('example'));
(3)样式的使用:React推荐使用内联样式,我们可以使用camelCase语法来设置内联样式React会在指定元素数字后自动添加px.
(4)注释的使用:注释需要写在花括号内.
(5)数组的使用:JSX允许在模板中插入数组,数组会自动展开所有成员.
7.HTML标签和React组件的渲染
(1)React可以渲染HTML标签(strings)或React组件(classes).
(2)要渲染HTML标签,只需要在JSX里使用小写字母的标签名.
(3)要渲染React组件,只需创建一个大写字母开头的本地变量.
由于JSX就是JavaScript,一些标识符像class和for不建议作为XML属性名,作为替代。Reacr DOM 使用className和htmlFor来做对应的属性.
组件既是函数
对于一个独立组件而言,你可以把它看成一个javascript函数
对于函数而言,当你通过传递参数调用函数时,函数会返回给你一个值。相比之下,对于react组件而言,道理是相似的,你传递属性给组件,而组件会返回一个被渲染好的dom。
1.类组件 class User extends React.Component{} 面向对象的组件.
2.无状态组件(函数组件):没有state和this 父自定义属性,子组件用props来接收.
3.ES5组件 React.createElement()
React.createElement,接受三个参数,代表节点类型的字符串type, 代表节点属性的对象props,代表节点内容 children。
4.高阶组件(高阶函数) function Hoc(child){}
高阶组件本质上是一个函数,只是这种组件(函数)接收一个组件,返回一个新的组件。
高阶函数:接受的参数是函数或者返回值是函数
如数组遍历相关的(map,ruduce),定时器,Promise,高阶组件也是高阶函数
高阶函数的作用就是实现一个更加强大动态的功能
高阶组件的作用就是实现组件复用,节省内存
React 因为不同原因出现三种react组件方式
(1)函数式定义的无状态组件.
(2)Es5 原生方式React.createClass定义的组件.
(3)Es6 的extends r React.createClass定义的组件.
Key的作用:
React中的key属性,它是一个特殊属性,它的出现不是给开发者用的。简单来说,react利用key来识别组件,它是一种身份标示,每个key对象一个组件,相同的key,react会认为是同一个组件,这样后续相同的key对应的组件都不会被创建.
Key的注意事项:
1.index作为key是一种反模式.
(1)用key来标识数组创建子组件时,若数组的内容只是作为纯展示,而不涉及到数组的动态变更,其实是可以使用index作为key的.
diff算法:
增加了什么钩子函数,代替原来的什么钩子函数,有什么样的优势:
组件的状态:又名state
无状态函数式组件:
创建无状态函数式组成形式是从react0.14版本开始出现的。它是为了创建纯展示组件。这种组件只负责根据传入的props来展示,不涉及到要
当一个组件只有render函数的时候,我们就可以用一个无状态组件来定义这个组件。其实无状态组件就是一个函数,同时这个函数会接收一个props,也就是父组件传递过来的内容。此时可以直接用prop
s而不是this.props。
有状态组件就是一个类,无状态组件是一个函数;
区别:
1.(是否拥有state)有状态组件可以使用状态:state,无状态组件不能使用state;只有继承component这个组件它才能拥有state进行一些数据的存储和管理,仍然可以拥有props;
2.(生命周期)如果是有状态组件的话那么你就会拥有生命周期函数,无状态组件就不用有生命周期函数,因为数据的更改都是通过状态进行更改。使用props进行组件间的通信进行传值,如果要更改某一些数据的话使用的是state,既然数据可以发生变化那么它就会触发对应的生命周期函数;
什么时候使用有状态组件,什么时候使用无状态组件:
如果想要存储一些数据并且想要对这些数据进行增删改查那么就应该使用有状态的组件,如果只是单纯的处理一些逻辑就是用无状态的组件,我们更多应该是使用的是无状态的组件(因为如果是一个有状态的组件的话那么他就一定会触发生命周期定义的一些函数,一旦触发这些函数就会影响当前项目的运行,所以在尽可能的情况下使用无状态的组件,除非你对当前的组件不是很清晰是否要存储数据这个时候可能选择使用有状态的组件或者确定要拥有一些状态去存储数据那么就需要使用有状态的组件)状态的东西都会通过父级去传递,比如Persons,Header这些组件如果想用到数据的话我们可以通过传递的形式给它传递过去,即当前的数据能够进行统一的数据管理,比如说通过父级管理数据,其他组件如果想拥有这个组件的话可以通过传值的形式给它。
有状态组件能使用this,无状态组件不能使用this;
无状态组件相对普通组件的优势在:
无状态组件的性能比较高,因为它就是一个函数,而普通的组件是普通的JS里的类,这个类生成的对象里面还会有一些生命周期函数,它执行起来既要执行生命周期函数又要执行render。它执行的代码远比普通的函数执行要多,所以如果一个组件只有render函数就用无状态组件来定义性能会更好。
当我们去定义一个UI组件的时候,它只负责页面渲染没有任何页面逻辑操作的时候,UI组件一般都可以用无状态组件来定义。其实UI组件里做一些简单的数据处理也是可以的。
React.Component有三种手动绑定方法:可以在构造函数中完成绑定,也可以在调用时使用method.bind(this)来完成绑定,还可以使用arrowfunc来绑定,拿上
组件的类型:无状态函数式组件,类组件,hooks组件 高阶组件
一个组件需要有自己的私有数据(this.state),推荐使用类创建的有状态组件
2)一个组件不需要有自己的私有数据,推荐使用function创建的无状态组件
高阶组件:高阶组件的作用就是实现组件复用,节省内存
组件中的props和state的区别
a)props是组件的配置,props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props可以包含数据和回调函数
b)state中是一种数据结构,用于组件挂载时所需数据的默认值,state数据都是组件私有的(通过ajax获取回来的数据,一般都是私有数据);state中的数据可读可写,可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果;
1)只能通过setState()方法修改state的值,不能 直接修改state因为这样不会重新渲染组件;
2)this.state必须在constructor中初始化为一个对象;
3)state的更新可能是异步的,所以setState()方法最好用回调函数;
Ref:
父子:父亲给儿子传一个属性名称,儿子添加值。
子父:子级给父级传值,首先父级给子级传递一个函数名称/方法,子级通过父级传过来的方法,把将要传给父级的值放入方法
子子:通过父亲作为桥梁,首先把父亲的方法传给儿子1,然后儿子1种添加的值,返回给父亲,然后父亲把值给儿子2。
一、Cookie
1、javascript cookie简单说,例如IE浏览器Cookie是网站向客户端主机C:\Document and Settings\Administrator\Local Settings\Temporary Internet Files
下创建的一个文本文件,里面春初网站相关信息。
用户再次访问此网站的时候服务器会读取这个Cookie文件,来获取相关信息
2、储存格式及属性
• cookie里面的名字使用的是“,”和“=”,不可以使用“;”
• cookie的保存格式为(每个属性之间通过:“分号+空格”(;)隔开;)
• Document.cookie="name=value;expores=evalue;path=pvalue;doman=dvalue;secure=svalue;"
3、cookie参数值的意思
• name:表示要存入对象的名称,唯一必须设置的参数(通常使用:user@domain格式命名:user为本地用户,domain为访问网站的域名)
• value:表示是要存入的值
• expires:该对象的有效时间(可选)(默认为当前浏览器会话有用,关闭浏览器就消失)
• path:指定该cookie作用范围(可选)(即在哪些网站上有效,默认情况下对于当前网页所在的同一目录下的所有页面有效)
• domain:设置web服务器的cookie共享域(可选)(如:test*.com)表示域名为test*.com的服务器共享该cookie
• secure:设置cookie的传输过程是否加密(可选)(一般为SSH加密)
4、cookie的限制
• Microsoft指出InternetExplorer8增加cookie限制为每个域名50个,但IE7似乎也允许每个域名50个cookie,lE6为20个。
• Firefox每个域名cookie限制为50个。
• Opera每个域名cookie限制为30个。
• Safari/WebKit貌似没有cookie限制。但是如果cookie很多,则会使header大小超过服务器的处理的限制,会导致错误发生。
注意:每个cookie文件大小不要超过4KB
二、storage
1、在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。
2、优势:
localStorage拓展了cookie的4K限制
localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的
3、缺点:
浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性
目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换
localStorage在浏览器的隐私模式下面是不可读取的
localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
localStorage不能被爬虫抓取到
1.组件方法外定义变量,将样式存储在变量中.
2.直接写在return返回的dom中,注意将css属性连接符“-”去掉后面的首字母大写.
3.在组件内引入css文件.
1.事件绑定三种:
(1)constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
(2)
(3)
17、router4有哪些router类型,需要注意的内容是什么,运行原理是什么
react-router 核心
react-router-dom(基于浏览器环境的开发)
react-router-native(基于react-native环境的开发)
安装 react-router-dom 或 react-router-native 时,都会自动将 react-router 作为依赖安装
原理
- 当用户触发了UI里的action时,action将被送到reducer方法里
- reducer就会更新数据层
- react数据也就是state (state包含在sotre里)
- state再去渲染UI
redux主要由三部分组成: store, reducer, action
l dispatch: 用于action的分发——在createStore中可以用middleware中间件对dispatch进行改造,比如当action传入dispatch会立即触发reducer,有些时候我们不希望它立即触发,而是等待异步操作完成之后再触发,这时候用redux-thunk对dispatch进行改造,以前只能传入一个对象,改造完成后可以传入一个函数,在这个函数里我们手动dispatch一个action对象,这个过程是可控的,就实现了异步
l action是一个对象,其中type属性是必须的,同时可以传入一些数据。action可以用actionCreator进行创造。dispatch就是把action对象发送出去
l reducer是一个函数,它接受一个state和一个action, 根据action的type返回一个新的state。根据业务逻辑可以分为很多个reducer,然后通过combineReducers将它们合并,state树中有很多对象,每个state对象对应一个reducer, state对象的名字可以在合并时定义
Redux-thunk :是通过settimeout去完成异步操作,当action创建时,触发action时,不直接去dispaly(派发)调用reducer,通过中间件,等一会再调用。实现异步。
和rudux-saga:只会在应用启动时调用,复杂时用到saga
Index.js 创建store reducer作为参数传入
Reducer方法中
增加删除的组件中 car.js
mock数据就是换成json数据即可
和本身的redux无关,只有用错时才会发生,(例如redux里边就不能嵌套redux,还有fetch应放在comdidmount
中,而不是comwillmount,否则会有一堆数据也删不掉,这也是回调地域),正常运用时就不会产生回调地域
高阶组件就是获取一个组件并返回一个组件的函数。
新组件=function(组件会参数)
Return组件
新组件就为高阶函数
用到:当点击一个添加弹出一个表单,就把这个表单作为高阶组件
应该放在compomentdidmount中,先有dom再有数据,
如果放在commentwillmout中,会有一堆数据而且删不掉,
就会发生回调地域。
在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,给设计师和工程师带来很多困扰和重复建设,大大降低了产品的研发效率。旨在统一中台项目的前端 UI 设计,屏蔽不必要的设计差异和实现成本,解放设计和前端的研发资源。
Ant Design 是一个致力于提升『用户』和『设计者』使用体验的中台设计语言。它模糊了产品经理、交互设计师、视觉设计师、前端工程师、开发工程师等角色边界,将进行 UE 设计和 UI 设计人员统称为『设计者』,利用统一的规范进行设计赋能,全面提高中台产品体验和研发效率。
代码中的回调函数套回调函数,这种回调函数中嵌套回调函数的情况就叫做回调地狱。回调地狱就是为是实现代码顺序执行而出现的一种操作,它会造成我们的代码可读性非常差,后期不好维护
从 16.8.0 版本开始,React 包含一个稳定的 React Hooks 实现,可用于:
请注意,要启用 Hooks, 所有 React 包都必须升级到 16.8.0 或更高版本。 如果你忘记更新诸如 React DOM 之类的包,Hooks 将无法运行。
Hook是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。Hook不能在class组件中使用——这使得你不使用 class也能使用 React。(我们不推荐把你已有的组件全部重写,但是你可以在新组件里开始使用 Hook。)(2020-5新更新解释)
以往 react 的组件都是以 class 形式编写, 只有无状态组件才可以用函数来编写.
Hooks 就允许我们在函数组件中使用预定义的内部函数来标记状态和组件生命周期, 使得几乎所有组件都可以用函数来编写.
Hooks 优势:
hook规则:(按照生命周期和功能给它单独封装,)
hook是JavaScript函数,但它们强加了两个额外的规则:
(1)只能在顶层调用Hooks。不要在循环,条件或嵌套函数中调用Hook.
(2)仅从React功能组件调用Hooks。不要从常规JavaScript函数中调用Hook.
1.作用:返回一个 state,以及更新 state 的函数,setState 函数用于更新 state。它接收一个新的 state 值并将组件的一次重新渲染加入队列。
2.用法:const [state, setState] = useState(initialState)
3.注意事项:useState 的参数可以是基本类型,也可以是对象类型,在更新对象类型时,切记要合并旧的状态,否则旧的状态会丢失
总结:利用 useState hook 可以让函数式组件拥有状态管理特性,它与传统的 class 组件的状态管理类似,但是更加简洁,不用频繁的使用 this。
作用:1.通过调用useEffect,你可以告诉 React 组件需要在渲染后执行某些操作。React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它。
用法:
注意事项:useEffect在组件mount(挂载)时会执行。但是在更新本地数据时,又会触发页面的重新加载,那么又回再次执行useEffect,如此下来,就会造成死循环。
那么,该如才能让useEffect如componentDidMount一样,只在加载的时候执行一次呢?
我们可以传递一个空数组作为useEffect的第二个参数,这样就能避免在组件更新执行useEffect,只会在组件mount时执行。
1.usereducer封装了reducer可以让函数组件使用reducer,useContext和usereducer配合使用(我们不用知道就行),useref是可以让函数组件使用ref。返回一个可变的 ref 对象,该对象只有个 current 属性,初始值为传入的参数( initialValue )。
2.返回的 ref 对象在组件的整个生命周期内保持不变。
3.当更新 current 值时并不会 re-render ,这是与 useState 不同的地方。
4.更新 useRef 是 side effect (副作用),所以一般写在 useEffect 或 event handler 里。
5.useRef 类似于类组件的 this。
promise:比较简单,也是最常用的,主要就是将原来的用回调函数的异步编程方法转成用relsove和reject触发事件,用then和catch捕获成功或者失败的状态执行相应代码的异步编程的方法。
Generator函数:是将函数分步骤阻塞,采用的是队列机制,只有主动调用next()才能进行下一步,yiled作用:相当于一个暂停开关,遇到next就会执行,主要用于需要异步并按顺序执行的封装函数可以使用generator
async函数:是es7新增的异步函数,采用的是generator语法糖,相当于自执行的Generator函数,相当于自带一个状态机,在await的部分等待返回,返回后自动执行下一步。返回的是promise对象,必须等到内部所有await命令后面的Promise对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。
相较于Promise,async的优越性就是把每次异步返回的结果从then中拿到最外层的方法中,不需要链式调用,只要用同步的写法就可以了。更加直观而且,更适合处理并发调用的问题。但是async必须以一个Promise对象开始,所以async通常是和Promise结合使用的
总结:总的来说,async和generator函数主要就是为了解决异步的并发调用使用的,直接将参数从then里取出来,相比promise的链式调用,传参更加方便,异步顺序更加清晰
(1)箭头函数没有自己的this对象。
(2)不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出
一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest
参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。
ajax :
●ajax 是XML HttpRequest对象的一个实例
●ajax 只有当状态为200或者304时才会请求成功
●ajax兼容性好,几乎所有主流浏览器都支持
fetch :
●fetch是ES6的规范,没有使用XMLHttpRequest对象
●fetch基于promise实现的,也可以结合async/await
●fetch请求默认不携带cookie, 需要设置init配置: credentials: include'
●fetch在接受到一个错误的HTTP状态码时(即使响应的HTTP状态码是404或500) ,返回的Promise不会被标记为reject, 相反,它会将Promise状态标记为resolve,仅当网络故障时或请求被阻止时,才会标记为reject
●fetch兼容性不好,所有的IE浏览器都不支持
在页面一开始打开的时候,React 会调用render函数构建一棵 虚拟DOM树,在state/props发生改变的时候,render函数会被再次调用渲染出另外一棵虚拟DOM树,接着diff算法会判断两棵dom树的差异,把差异更新到真实DOM中去。
React基于两个假设:
a.两个相同的组件产生类似的DOM结构,不同组件产生不同DOM结构
b.对于同一层次的一组子节点,它们可以通过唯一的 key区分
①节点类型不同,react 会直接删去旧的节点,新建一个新的节点。
②节点类型相同,但是属性不同,只改变需要改变的属性。
③列表比较,为每个子元素添加一一个唯一的key,React使用key将原始树中的子元素与后续树中的子元素进行匹配。
真实dom:更新慢,可以直接更新html,如果元素更新,则创建新dom,dom操作代价高,消
耗内存较多。
虚拟dom:虚拟DOM就是一个 js对象,他有tag, props,和children属性,虚拟DOM更新快,无法直接更新Html,如果元素更新,则更新虚拟DOM操作非常简单很好的内存消耗。计时器
1.用js对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中。
2.当状态变更的时候,重新构造一棵新的对象树。然后对比新旧虚拟DOM树,记录两棵树
差异。
3.把差异应用构建的真正的DOM树上,视图就更新了。
原因:虚拟dom相当于在is和真实dom中间加了一个缓存,利用diff算法减少了对真实DOM的操作次数,从而提高性能。
1、单一数据源。
2.状态是只读的。
3、状态的改变只能通过纯函数操作。