本人是个新手,写下博客用于自我复习、自我总结。
如有错误之处,请各位大佬指出。
学习资料来源于:尚硅谷
专栏简述
笔者之前认为只学习Vue并能熟练运用已经够用了,不过随着工作时长的增加,身边的朋友反复推荐:如果有时间的话,学学React没有坏处。确实如此。从某种程度上来说,React和Vue还是比较像的,而笔者又是先学习的Vue,这突然间让我接受看起来更“繁琐”的React,累觉不爱。
笔者又从坊间听到了很多传闻(以下言论不代表笔者观点),比如:国内大部分使用Vue,国外大部分使用React,但是国内大厂都在使用React。虽然这些数据笔者无法验证,但我们在npm官网可以看到全世界范围内Vue和React的使用情况:(图片截选日期 2020/12/16)
近期又看了看,数据基本没有太大差异。那造成几乎近五倍差距的原因是什么,这让我对React产生了一丝兴趣,到底React的优势在哪,使用Vue不是更简单轻松吗?
那么接下来将会花一段时间先介绍React的基础用法。
以下为React的官网,大家也可以选择参照官方文档进行学习:
- 英文官网: https://reactjs.org/
- 中文官网: https://react.docschina.org/
React的特点
-
Declarative(声明式编码)
-
Component-Based(组件化编码)
-
Learn Once, Write Anywhere(支持客户端与服务器渲染)
-
高效
-
单向数据流
具体的这些特点,将会在后续的学习中逐渐体会到。
对于React高效的原因(之后还会具体解释):
- 虚拟(virtual)DOM, 不总是直接操作DOM
- DOM Diff算法, 最小化页面重绘
如果学习过Vue应该知道,Vue就是借鉴的React的组件化和虚拟DOM技术。
那么React和Vue的Diff算法有没有区别呢?感兴趣的可以看一看:vue和react的diff算法简单比较
React的基本使用(测试语法)
在这里为了方便测试语法,先不创建项目,相关的js库,大家可以去BootCDN上查找:https://www.bootcdn.cn/react/
这里需要说明的是,它分为开发版和生产版(带min),我们使用开发版即可,生产版是进行压缩过后用于上线的。
当我们想引用时,可以直接复制成script标签使用,也可以保存到本地使用,我选择保存到本地。保存到本地只需要点击下方链接到新网页,然后ctrl+s保存,即可以保存到本地。
下载链接:
react.development.js
react-dom.development.js
babel.min.js
之后总共会用到四个文件:
- react.js: React的核心库
- react-dom.js: 提供操作DOM的react扩展库
- babel.min.js: 解析JSX语法代码转为纯JS语法代码的库
- prop-types.js:主要用来项目类型检测(暂时将不会使用,感兴趣的可以先去看看:prop-types的使用讲解)
JSX理解和基本使用
在写HelloWorld前,先来看看何为JSX。
关于JSX:
-
全称: JavaScript XML
-
它是react定义的一种类似于XML的JS扩展语法: XML+JS
-
作用: 用来创建react虚拟DOM(元素)对象
用法:var ele = <h1>Hello JSX!</h1>
注意: 它不是字符串, 也不是HTML / XML标签,它最终产生的就是一个JS对象
( 当然,JS本身不能这么做,我们需要导入上述React的核心库,随后就可按下面所述的基本语法规则来解读 ) -
标签名: HTML标签或其它标签
-
标签属性: HTML标签属性或其它属性
-
基本语法规则(※)
a. 遇到<
开头的代码, 以标签的语法解析:html同名标签转换为html同名元素,其它标签需要特别解析
b. 遇到以{
开头的代码,以JS语法解析:标签中的js代码必须用{ }
包含 -
babel.js的作用
a. 浏览器不能直接解析JSX代码, 需要babel转译为纯JS的代码才能运行
b. 只要用了JSX,都要加上type="text/babel"
, 声明需要babel来处理
需要指出的是,使用JS方式也可以去创建虚拟DOM元素对象,那React为什么要使用这种方式呢:在 React 中使用 JSX 的好处。它们的使用差异会在写完HelloWorld之后展示。
在这里需要记住这个基本语法规则,之后我们可以在创建虚拟DOM元素对象时更加灵活。
关于渲染虚拟DOM(元素)
-
语法:
ReactDOM.render(virtualDOM, containerDOM)
-
作用: 将虚拟DOM元素渲染到页面中的真实容器DOM中显示
-
参数说明
a. 参数一: 纯 js 或 jsx 创建的虚拟dom对象
b. 参数二: 用来包含虚拟DOM元素的真实dom元素对象( 一般是一个div )
介绍完这些在HelloWorld中测试。
HelloWorld
我们想要使用React先把上面提到的三个js导入,然后在下面的代码中一定要注意!必须声明babel,告诉babel去解析里面的JSX代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HelloWorld</title>
</head>
<body>
<div id="test"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel"> //必须声明babel,告诉babel去解析里面的jsx代码
// 1、创建虚拟DOM元素对象
const vDom = <h1>Hello React</h1> // 不是字符串:不要加引号
// 2、渲染虚拟DOM到页面真实DOM容器中
ReactDOM.render(vDom, document.getElementById('test'))
</script>
</body>
</html>
从效果来看,我们已经将内容添加到了页面中:
JS和JSX的使用对比
不用React单纯只用JS的,相信各位在学习JS的时候就接(折)触(磨)过了,在这里就不演示了。
那我们在使用React的基础上,如果不用JSX,React也提供了一种用JS去创建虚拟DOM元素对象的方法:React.createElement(标签名,{标签id},标签体内容)
。比原生JS简练的多。
而如果使用JSX,因为基本语法规则的存在,我们就能够更直观简单的完成这部分内容。
代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSX</title>
</head>
<body>
<div id="test1"></div>
<div id="test2"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/javascript">
// 1. 创建虚拟DOM
/*方式一: 纯JS(一般不用)创建虚拟DOM元素对象*/
const msg = 'test'
const myId = 'React'
//虚拟DOM对象最终都会被React转换为真实的DOM
//编码时只需操作react的虚拟DOM相关数据, react就会将其转换为真实DOM变化而更新界面
//createElement(标签名,{标签id}, 标签体内容)
const vDOM1 = React.createElement('h2', {id: myId}, msg.toUpperCase())
// 2. 渲染到真实页面
const domContainer = document.getElementById('test1')
ReactDOM.render(vDOM1, domContainer)
</script>
<script type="text/babel">
// 1. 创建虚拟DOM
/*方式二: JSX创建虚拟DOM元素对象*/
const vDOM2 = <h3 id={myId.toUpperCase()}>{msg.toLowerCase()}</h3>
// 2. 渲染到真实页面
ReactDOM.render(vDOM2, document.getElementById('test2'))
</script>
</body>
</html>
通过对比,我相信各位最大的感受就是JSX确实方便且直观,易于接受。那在使用的就需要注意之前提到的语法规则:
遇到<
开头的代码, 以标签的语法解析:html同名标签转换为html同名元素,其它标签需要特别解析。
遇到以{
开头的代码,以JS语法解析: 标签中的js代码必须用{ }
包含。
在了解了以上内容后,简单应用一下。
例:动态展示列表数据
通常情况下,我们会从接口获取到数据。现在假设将其存储到了某数组中。
var names = ['jquery', 'zeptoo', 'angular', 'react全家桶', 'vue全家桶']
因为在构建页面时,不知道会从接口获取到多少数据,所以原div
标签中没有设置ul
li
标签。
在认识到React之后,因为它JSX的语法规则,所以我们只要在JSX中创建标签(虚拟DOM对象)并渲染到页面中即可。
现在只是想要将其简单的通过 ul
li
展示到页面中,不考虑CSS,一共有两种方法。
第一种: 再创建一个数组去存储变成标签形式的各数据内容,然后将该数组拿去渲染。
第二种: 直接在创建虚拟DOM时,将该组标签设置好,然后拿去渲染。
在以下代码中将会涉及到以下非React内容,如有不了解的知识点可以去补习一下:
(1)箭头函数
(3)forEach的使用
除此以外,React能自动遍历显示数组中所有的元素。具体内容请看以下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>例_JSX_DEMO</title>
</head>
<body>
<h2>前端JS框架列表</h2>
<div id="example1"></div>
<div id="example2"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
/* 功能: 动态展示列表数据 */
// 数据的数组
var names = ['jquery', 'zeptoo', 'angular', 'react全家桶', 'vue全家桶']
// 方法1:
// 数据的数组-->标签的数组
var lis = []
names.forEach((name, index) => lis.push(<li key={index}>{name}</li>))
// 创建虚拟DOM,遇到{将会用JS解析
// React能自动遍历显示数组中所有的元素
const ul = <ul>{lis}</ul>
// 渲染虚拟DOM
ReactDOM.render(ul, document.getElementById('example1'))
// 方法2:
// 创建虚拟DOM,遇到{将会用JS解析
// React能自动遍历显示数组中所有的元素
const ul2 = <ul>{
names.map((name, index) => <li key={index}>{name}</li>)
}</ul>
// 渲染虚拟DOM
ReactDOM.render(ul2, document.getElementById('example2'))
</script>
</body>
</html>