React新版V16---基础教程
链接:React16基础教程
前言:
首先不能否认React.js是全球最火的前端框架(Facebook推出的前端框架),国内的一二线互联网公司大部分都在使用React进行开发,
比如阿里、美团、百度、去哪儿、网易 、知乎这样的一线互联网公司都把React作为前端主要技术栈
大纲:
01_React免费视频课程介绍 02_React简介和Vue的对比 03_React开发环境的搭建 04_React项目文件目录介绍 05_HelloWorld和组件化开发 06_JSX语法简单介绍 07_React实例小姐姐服务菜单 08_React实例宝剑磨的好理论少不了 09_React实例老板我要加个钟 10_React实例宝剑虽然好老腰受不了 11_JSX防踩坑的几个地方 12_Simple React Snippets插件的使用 13_Component 组件的拆分 14_父子组件的传值 15_单项数据流和其它 16_调试工具的安装及使用 17_PropTypes校验传递的值 18_ref属性的使用与setState异步回调 19_React生命周期函数讲解 20_React生命周期函数讲解 21_React生命周期函数讲解 22_React生命周期改善组件性能 23_React用Axios请求远程数据 24_Axios请求EasyMock数据 25_用CSS3实现React动画 26_CSS3的keyframes动画 27_react-transition-group动画库学习 28_多DOM动画制作和编辑
(1)01_React免费视频课程介绍
(2)02_React简介和Vue的对比
官网简介:用于构建用户界面的jS库
使用人数最多,拥有全球最健全的文档和相关体系
V16版本开始改动较大,新增了很多新的API
(3)03_React开发环境的搭建
前提:安装node和npm,新版本的npm已经内置于node,安装完毕后进行验证,检验是否完成安装
接下来全局安装官方推荐的脚手架工具create-reate-app,当然还有其他脚手架工具,不过建议使用官方推荐
接下来创建项目
接下来运行项目
(4)04_React项目文件目录介绍
1、README.md项目说明文件
一般开发时都会将原先内容删除,改为自定义,利用MarkDown语法,首先我们启动live-server,在浏览器进行预览
這裡我安装了拓展工具,所以Markdown Reader,所以可以直接在浏览器查看效果。这里我们将原先内容删除,开始手动编辑。
如下所示:
最后等我们上传到GitHub,会直接显示成文档格式,方便他人阅读使用
2、package.json项目说明文档
一、生产环境依赖
二、工程化相关指令
三、package-lock.json锁文件
锁定依赖树及依赖版本,相当于项目的依赖版本控制文件,防止依赖包的依赖包因为版本升级带来的问题。
四、.gitignore为忽略上传文件
五、node_modules依赖包
六、public公共文件
1、favicon.ico为网页logo 2、index.html为SPA的模板文件
3、manifest.json移动端配置文件
index.html里有noscript如下所示
作用:工程化项目的容错处理<noscript></noscript>,兼容处理,如果js开启失败则提示。
七、src目录
项目代码根目录,主要用于存放项目源码。
一、入口文件为index.js
1、import APP from './APP'中./APP为./APP.js的简写,webpack默认识别机制可以自动识别到App.js,作为一个有追求的程序猿,我们肯定要装一下... ...
2、import * as serviceWorker from './serviceWorker'主要与PWA相关,PWA(渐进式web应用)是由谷歌提出的移动端技术,离线缓存技术.
3、serviceWorker.unregister();也是用来做这个文件可以视情况用或者不用,它是用来做离线缓存等任务的,实际上就是为react项目注册了一个service worker。
这样的话,如果在线上,只要访问过一次该网站,以后即使没有网络也可以访问(此时使用的是之前缓存的资源)。详见React工程化之PWA之serviceWorker.
(5)05_HelloWorld和组件化开发
接下来删除src下所有文件,从头开始编辑
1、首先编写入口文件index.js
2、编写根组件
解构赋值写法
结果如下
这里我们推荐组件后缀为JSX,因为JSX后缀文件里的HTML语法有对应语法提示,而JS后缀文件则没有提示
(6)06_JSX语法简单介绍
JSX全称为javascript and xml,利用HTML创建虚拟DOM,虚拟DOM不占用页面的渲染机制,从而快速反应相关动作。
JSX语法规则:
JSX语法里,遇到<>时会将其识别为XML语法,遇到{}时会识别为JS语法
JSX 语法优势(对比纯JS语法):
支持三元运算符
(7)07_React实例小姐姐服务菜单
结果如下
碎片化管理Fragment,解除单个根元素限制
与Vue类似,React组件同样有单个根元素限制,但某些情况下不能在外层包裹div,可能破坏flex布局,所以此时可以通过碎片化属性Fragment解除该限制,如下所示
如下所示
flex弹性布局经常使用碎片化属性Fragment解除单个根元素限制
(8)08_React实例宝剑磨的好理论少不了
知识点:React中的响应式设计原理和数据绑定方法.
要求:点击增加服务时,列表添加新增服务。之前的做法为操作DOM进行添加,但React为数据驱动,页面的UI变化都是通过数据驱动的,避免直接的DOM操作,设计模式为MVVM模式,不必关注样式操作,React会自动帮我们完成。接下来在构造器里继承Component初始化
注意:
在constructor构造器里继承了React.Component后,才可以使用this.state进行状态初始化
接下来进行数据绑定
数据绑定完毕后,在页面无法编辑和删除输入框值,此时还需要进行事件绑定,改为可控组件
接下来进行事件定义,首先改动this指向
修改state状态
小结:
对比之前的JS,React语法有了很大改动,例如this指针的指向、数据驱动、如何改动、事件绑定等... ...
(9)09_React实例老板我要加个钟
目前为止,输入框已经变成了可控组件,已经可以正常编辑,接下来做个完善,输入内容后点击按钮,将内容添加至列表项。因为React是数据驱动,所以接下来进行数据操作
首先初始化state的数据
接下来循环数据
接下来添加按钮事件绑定
接下来利用ES6的扩展运算符语法,补充数组元素。(下面案例中两者作用一致),使数组结构更加直观
此时点击按钮,便可以实现添加列表操作
审查代码,出现key警告
添加元素定向跟踪,一般不建议直接使用index,因为索引不具备唯一性,这里我们可以使用index+item,增加其不重复的机率。很多开发者经常使用该方法.
接下来重置输入框
(10)10_React实例宝剑虽然好老腰受不了
接下来做个列表删除功能,首先给列表元素绑定点击事件
此时定义事件,测试传入的index参数
接下来实现数组元素删除
此时便可以实现正常的删除功能,但需要注意的是:这里有个初期学习者容易遇到的坑
即React官方不建议直接操作state状态集合里面的属性。
如果想操作的话,最好先赋值给一个变量,再操作该变量,不然后期可能会遇到性能问题。使得产品性能受到较大的影响
(11)11_JSX防踩坑的几个地方
1、JSX代码注释(单行与多行)
这里的{}使得JSX识别其为JS代码,然后里面才能开始使用JS注释语法进行注释。此外如果想用单行注释语法,只能写成如下
2、class类名
例如这里我们将边框颜色设置为#ae7000屎黄色,这种黄色浓度较浅。接下来进行引入
这里注意元素类名必须用ClassName,因为要和ES6的class做区分
3、解析输入的HTML元素
如下所示,想要将我们输入的元素内容进行转换,渲染出对应的元素样式
此时需要用到一个属性dangerouslySetInnerHTML译为:危险地设置InnerHTML.
此时便将输入内容解析渲染成了对应元素。
4、关联标签label的htmlFor
JSX里为了防止label的for属性与JS的for循环冲突,React将label的for属性改为labelFor
(12)12_Simple React Snippets(简单反应片段--快速生成代码)插件的使用
简单测试如下
1、imrc
2、cc
3、ccc
(13)13_Component 组件的拆分
将上面输入框和按钮拆成一组,将下面列表拆分为另一组
首先将之前的代码进行相关注释,如下所示
接下来直接将编写的其他拆分组件引入即可
但此时仍然存在不足,即添加的内容尚未实现
此时便需要用到props属性实现父组件向子组件传递数据的功能
(14)14_父子组件的传值props
上面的输入项和按钮拆分成了一个组件,底下的列表项在这里调用,若要实现输入内容展示在列表组件,则必须通过组件通信,即父组件传值到子组件渲染
首先进行父组件传值
然后在字组件进行接收
此时便可以接受父组件传递过来的值了
此时也可以实现输入内容的列表添加
但仍然无法实现点击列表项时的删除,因为列表数据存放在父组件,所以此时便视为子组件传递到父组件,即子--->父
首先必须明确,React于Vue类似,子组件不能直接编辑修改父组件数据
子组件添加绑定事件,将对应的index索引传递过去,如下所示
然后在子组件进行接收
此时便可以获取对应索引,这里注意bind绑定修改this指向。除了在调用处绑定,也可以在constructor构造器处绑定,建议绑定到构造器,对于后期项目性能优化有好处。
接下来编写删除操作,首先将父组件里的删除方法传递给字组件
然后在子组件接受调用,如此便实现了父子组件的通信
接下来做个自定义案例,如下所示,点击按钮时,子组件的数据是由父组件传递过来的,但在字组件的按钮触发时,除了改变子组件本身外,还改变父组件状态
import React,{Component,Fragment} from 'react' import Test from './Test.jsx' /* ES6解构赋值写法 等价于 import React from 'react' const Component = React.Component */ class App extends Component { constructor(props){ super(props) this.state = { money:100 } this.addNumber = this.addNumber.bind(this) } render(){ return( <Fragment> <h1>我是父组件,我有{this.state.money}</h1> <Test toChild={this.state.money} toAddFn={this.addNumber}></Test> </Fragment> ) } addNumber(){ let num = this.state.money; num++; this.setState({ money:num }) } } export default App
Test.jsx代码
import React, { Component ,Fragment} from 'react'; class Test extends Component { constructor(props) { super(props); this.state = { } this.childAddFn = this.childAddFn.bind(this) } render() { return ( <Fragment> <h2>我是子组件Test,父组件传递过来{this.props.toChild}</h2> <button onClick={this.childAddFn}>+</button> </Fragment> ) } childAddFn(){ this.props.toAddFn(this.props.toChild) } } export default Test;
类似于Vue的自定义$edit()事件传值,同样实现了子组件向父组件的通信
(15)15_单项数据流和其它
1、单向数据流
父组件可以直接向子组件传值,但子组件不能直接修改父组件传递过来的值,如果在子组件里直接修改父组件传递过来的值,则会报错。如下所示
为什么设计单向数据流?
保证数据的稳定性,可能一个组件在很多地方调用,如果是双向数据流,则容易造成冲突
2、React是否可以和其他框架jquery等结合使用
答案是可以
这里的React仅仅控制id为root的元素,针对其他元素可以随意控制
3、函数式编程
函数式编程优势:
1、代码结构清晰,如下所示
2、方便测试和后期维护,使得配合和测试更加方便高效
(16)16_调试工具的安装及使用
Facebook为了方便调试React代码,推出了React Developer Tools调试工具,方便开发者高效快速调试代码。下载方式,利用Chrome的拓展程序
添加后该图标便会放到页面右上角,该图标有几种状态,测试如下
1、打开淘宝发现图标灰色,说明淘宝没有使用react
2、打开知乎,发现右上角的react图标高亮变成黑色,说明该网站利用了react技术进行开发。
该网站使用React技术开发,通过webpack进行打包压缩混合,运行在了服务器,使其可以在生产环境中使用。
3、打开自己编写中的网页,发现右上角react图标高亮成屎黄色
表明该网页运用了React技术,在当前开发测试环境中开启了调试工具
打开控制台即可进行调试
(17)17_PropTypes校验传递的值
基本类型校验:
之前的案例中,父组件向子组件传递的数据里,并没有做数据类型校验
虽然正确传递和使用了,但是在子组件里并没有做传递数据的类型验证,也就是说,此时传递任何值都不会报错。
开发经验丰富的小伙伴都知道,当项目复杂性较大时,如果不对数据类型做校验,后期很容易出现一种错误,即“业务逻辑错误”。 业务逻辑错误一般也是在开发时最为难找的错误,可能数据传递来传递去出了问题,这种问题不像语法错误很好找,为了避免这种错误,我们在开发时都要进行数据校验。 此时便需要借助React的prop-types,如下所示,在子组件引入校验对象并进行校验
这里注意PropTypes的命名法则是默认俗称的,为了方便团队合作,一般都会使用默认俗称的命名
此时便对传递的数据类型做了相应的校验,如果不符合数据类型则会在控制台出现警告提示
必填项校验:接下来添加其他数据,如下所示
如果父组件不传递数据,此时也不会报错提示。这显然是不符合开发规范的
接下来做必填项验证:传递数据为字符串类型且为必填项
接下来进行传递才不会报错
默认值校验设置:
(18)18_ref属性的使用与setState异步回调
ref的存在增加了代码语义化,如下所示,输入框即自定义的可控组件在输入时触发onChange事件,改变state状态值为e.target.value,但该写法语义化程度不佳。
这里我们可以使用ref来进行操作
这里我们将该输入框input绑定给了this.input,那么之前的获取输入框值的操作便可以修改如下
我们给 input 元素加了一个 ref 属性,这个属性值是一个函数。当 input 元素在页面上挂载完成以后,React.js 就会调用这个函数,并且把这个挂载以后的 DOM 节点传给这个函数。
在函数中我们把这个 DOM 元素设置为组件实例的一个属性,这样以后我们就可以通过 this.input 获取到这个 DOM 元素
通俗理解:
ES6箭头函数+React规定,ref 属性的属性值是一个函数,当元素挂在完毕后,React.js 就会调用这个函数,并且把挂载的 DOM 节点传给这个函数,即这里的input便是挂在后的DOM节点
这里一眼便知道了这里是获取input输入框的值,语义化程度也提高了很多。关于ref的用法详解React之ref操作DOM(ref = {input=>this.input = input}).这里是ref的回调函数用法。
再例如获取li的数量
测试如下
此时发现问题,即控制台获取的li的数量永远少一个???
之所以出现这种问题,因为setState是异步操作,该方法操作虚拟DOM需要一定的时间,所以会优先输出同步方法的console.log()
为了解决该问题,新版的React给setState添加了回调函数,如下所示
测试如下,此时便可以正常获取
(19-21)19-21_React生命周期函数讲解
(22)22_React生命周期改善组件性能
(23)23_React用Axios请求远程数据
(24)24_Axios请求EasyMock数据
(25)25_用CSS3实现React动画
详见React动画相关(CSS3、eact-transition-group动画库、多DOM动画制作和编辑).
(26)26_CSS3的keyframes动画
详见React动画相关(CSS3、eact-transition-group动画库、多DOM动画制作和编辑).
(27)27_react-transition-group动画库学习
详见React动画相关(CSS3、eact-transition-group动画库、多DOM动画制作和编辑).
(28)28_多DOM动画制作和编辑
详见React动画相关(CSS3、eact-transition-group动画库、多DOM动画制作和编辑).
.