前言
网页是B/S架构中最重要的信息载体,用户看到的所有信息都需要在网页中呈现。像商品信息、用户信息、新闻列表等一系列的内容都需要通过网页的形式呈现出来。在传统的网站中用户每点一次链接就会加载出一个新的页面。比如用户在网站的主页中看到了一个新闻的标题,点击标题网站会跳转到一个新的页面来展示新闻的具体内容。这样就导致呈现新闻的页面是从服务器中新加载出来的,新闻和首页是两个完全独立的页面。如果本来两个页面就没有什么太大的关系这么处理当然是没有问题的,但有些使用场景中却不能这样。
在有些场景中,用户在网页中发生了一些行为,比如登录、加购物车、添加删除等操作时,这些操作的确会使网页发生变化,但这些变化往往非常细微,比如购物车图标的产品数量发生了变化,登录按钮变成了用户头像,网页中增加或减少了一条数据等。如果仅仅因为这些小的变化就刷新了整个网页是有些划不来的。刷新整个网页一来会增加用户的等待时间,二来也会增加服务器的压力。于是我们就有了局部刷新网页的技术。
所谓的局部刷新指的是,当用户和网站发生交互时,我们不再是简单的直接通过浏览器进行页面的跳转,而是通过JS中的AJAX直接通过JS向后台服务器发送请求,请求过程用户毫无感知。响应数据会通过回调函数返回给JS,而不是直接返回给用户。JS中收到响应数据后,在根据不同的结果通过DOM来完成对页面的修改。它的优点就是,请求响应过程是异步的,用户是无感的,不会影响用户的其他操作。同时,通过DOM对页面刷新时只需刷新部分页面无需整体刷新,提高了访问速度。在服务器端,服务器只需提供数据接口,无需考虑页面的渲染,在降低服务器复杂度的同时也使得服务器压力降低提高了处理请求的速度。
AJAX + DOM使得局部刷新成为了可能,但一切似乎并不是那么的完美。发送请求加载数据问题不大,但数据一旦加载过来问题就出现了。数据并不能直接在网页中显示。我们需要通过DOM将数据转换为网页的中的各种节点,这就意味着我们必须反复的操作DOM,这其中的痛苦实在是一言难尽。一来DOM操作本身十分占用系统资源一不小心就会出现卡顿。二来DOM的API十分繁复,使得各种操作并不十分的优雅。换句话说,服务器的复杂度降低了,但是前端的复杂度提高了。
于是在前端开发中就急需一个框架来帮助我们解决这个问题,使我们可以比较轻松的根据不同的数据来快速构建用户界面(UI),与此同时还要在构建过程中确保其流畅度(不能出现卡顿)。于是React、Angular、Vue这些前端框架应运而生。
React简介
React 是一个用于构建用户界面的 JavaScript 库,用来为现代的网络构建用户界面。React起源于Facebook,由Facebook的软件工程师 Jordan Walke 开发,2012年部署于 Instagram,2013年开源。除此之外,React还有React Native框架,通过它让我们可以直接使用 JavaScript 来编写原生应用。
React的特点:
- 虚拟DOM
- 声明式
- 基于组件
- 支持服务器端渲染
- 快速、简单、易学
HelloWorld
React的常规开发方式并不是通过浏览器引入外部js脚本来使用,但在入门阶段我们暂且先使用这种方式来简单体会一下React。
使用React开发Web项目,我们需要引入两个js脚本:
react.development.js
- react 是react核心库,只要使用react就必须要引入
- 下载地址:https://unpkg.com/react@18.0.0/umd/react.development.js
react-dom.development.js
- react-dom 是react的dom包,使用react开发web应用时必须引入
- 下载地址:https://unpkg.com/react-dom@18.0.0/umd/react-dom.development.js
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>Hello React</title> <script src="script/react.development.js"></script> <script src="script/react-dom.development.js"></script> </head> <body> <div id="root"></div> <script> const button = React.createElement('button', { onClick: (e) => { alert('你点了按钮!'); e.stopPropagation(); } }, '我是一个按钮'); const box = React.createElement('div', { onClick: (e) => { alert('你点了div!'); console.log(e); } }, '我是一个div', button); const root = ReactDOM.createRoot(document.querySelector('#root')); root.render(box); </script> </body> </html>
三个API
React.createElement()
React.createElement(type, [props], [...children])
- 用来创建React元素
- React元素无法修改
ReactDOM.createRoot()
createRoot(container[, options])
- 用来创建React的根容器,容器用来放置React元素
root.render()
root.render(element)
- 当首次调用时,容器节点里的所有 DOM 元素都会被替换,后续的调用则会使用 React 的 DOM 差分算法(DOM diffing algorithm)进行高效的更新。
- 不会修改容器节点(只会修改容器的子节点)。可以在不覆盖现有子节点的情况下,将组件插入已有的 DOM 节点中。
JSX(JavaScript Syntax Extension)
JSX 是 JavaScript 的语法扩展,JSX 使得我们可以以类似于 HTML 的形式去使用 JS。JSX便是React中声明式编程的体现方式。声明式编程,简单理解就是以结果为导向的编程。使用JSX将我们所期望的网页结构编写出来,然后React再根据JSX自动生成JS代码。所以我们所编写的JSX代码,最终都会转换为以调用React.createElement()
创建元素的代码。
const element = <h1>Hello, world!</h1>; // React.createElement('h1', {}, 'Hello, world!')
const name = 'Josh Perez'; const element = <h1>Hello, {name}</h1>; const root = ReactDOM.createRoot(document.querySelector('#root')); root.render(element);
function formatName(user) { return user.firstName + ' ' + user.lastName; } const user = { firstName: 'Harper', lastName: 'Perez' }; const element = ( <h1> Hello, {formatName(user)}! </h1> ); const root = ReactDOM.createRoot(document.querySelector('#root')); root.render(element);
注意事项:
- 不要加引号
- 有且只有一个根标签
- html标签小写开头,React组件大写开头
- 可以使用{}插入JS表达式。(表达式:有返回值的语句。JSX也是表达式)
- 属性正常写(class使用className,style必须用{})
- 标签必须正常闭合
- 布尔类型、Null 以及 Undefined 将会忽略
由于JSX最终需要转换为JS代码执行,所以浏览器并不能正常识别JSX,所以当我们在浏览器中直接使用JSX时,还必须引入babel来完成对代码的编译。
示例:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Hello React</title>
<script src="script/react.development.js"></script>
<script src="script/react-dom.development.js"></script>
<script src="script/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
const h1 = <h1>Hello React</h1>;
ReactDOM.render(h1, document.querySelector('#app'));
</script>
</body>
</html>
babel下载地址:https://unpkg.com/babel-standalone@6/babel.min.js
在JSX中可以直接通过 {} 来嵌入 JS表达式,所谓的表达式指的是有返回值的语句。比如可以直接在JSX中嵌入值或变量像这样:
const name = '孙悟空';
const ele = <h1>Hello {name}</h1>;
const ele2 = <h1>Hello {孙悟空}</h1>;
const ele3 = <h1>1 + 1 = {1 + 1}</h1>;
{} 中也可以调用函数:
function fn(){
return '哈哈';
}
const ele = <h1>{fn()}</h1>
没有返回值的语句,像if、for等语句是不能出现在JSX中的!但是在if、for等里边写JSX是可以的:
let ele;
let isLogin = true;
if(isLogin){
ele = <h1>欢迎光临!</h1>;
}else{
ele = <h1>请登录!</h1>
}
let eles = [];
for(let i=0; i<5; i++){
eles.push(<h2>我是第{i}个h2</h2>);
}
超哥威武
李老师,如何才能在Typescript中用React框架?
我也想问一下,怎么在tsconfig.json里配置React
引入的包要改为:https://unpkg.com/react@18.2.0/umd/react.development.js
不然运行了会空白没有效果哦