React
React前言
官方文档
- React 18 中文文档1(国内社区):https://react.docschina.org/
- React 18 中文文档2(官方):https://zh-hans.reactjs.org
- React 18 英文文档:https://reactjs.org
- React 17 英文文档:https://17.reactjs.org
react概述
-
React 是一个用于动态构建用户界面的 Js 库
-
起源于 Facebook ,并于 2013 年 5 月开源
-
当前最新版本是18的版本
- 2020升级为17版本(变化特别大,添加hook语法)
- 2022升级为18版本(变化不大)
-
React本身只关注界面,其它如:前后台交互、路由管理、状态管理等都由其它插件搞定
react特点
1.声明式
react利用JSX 语法来声明描述动态页面, 数据更新界面自动更新
React.createElement() 是命令式
声明式&命令式
-
声明式
只需更新数据,具体操作不需要写
声明式不用我们亲自操作原生DOM就能去做页面的动态初始显示和更新显示,使用 JSX 语法来描述页面,只要更新状态数据界面就会自动更新
-
命令式
声明式的反面是命令式
命令式即具体如何操作需要我们自己定义
2.组件化
- 将一个较大较复杂的界面拆分成几个可复用的部分,封装成多个组件, 再组合使用
- 组件可以被反复使用
3.一次学习 随处编写
- 不仅可以开发 web 应用(react-dom)
- 还可以开发原生安卓或ios应用(react-native)
4.高效
- React虚拟DOM
- React 虚拟 DOM Diff 算法(高效更新,更新时不是全部更新)
React基础
基本使用
步骤
-
引入两个JS文件
⚠注意文件引入顺序
react-dom.development.js基于react.development.js,顺序不可改
-
react17版本
<!-- 提供了React对象 --> <script src="./lib/17/react.development.js"></script> <!-- 提供了ReactDOM对象 --> <script src="./lib/17/react-dom.development.js"></script>
-
react18版本
<!-- 引入react库,提供React对象 --> <script src="./lib/react18/react.development.js"></script> <!-- 引入react-dom库,提供ReactDOM对象 --> <script src="./lib/react18/react-dom.development.js"></script>
-
-
在html定义一个根容器标签
一般id值为root或app
<div id="root"></div>
-
创建react元素
react元素类似html元素
中括号代表参数是可选的,可以不传
React.createElement( type, //标签名 [props], //包含所有标签属性的对象 children1, children2... //任意多个子节点,可能是字符串,也可能是react元素 ) const element = React.createElement( 'h1', { title: '你好, React!'}, 'Hello React!' ) //有标签子节点,在children处创建新的react元素 //没有属性,则传空对象{}或者null const element = React.createElement( "h1", { title: "你好, React!" }, React.createElement("p", { }, "Hello1"), React.createElement("p", null, "Hello2") );
-
渲染 react 元素
react18 与 react17 版本在渲染react元素的API上不一样
新项目更多的使用18,而旧的项目可能用的就是17的版本
-
react17版本
ReactDOM.render( element, //react元素 container //页面渲染元素的容器元素 ) ReactDOM.render(element, document.getElementById('root'))
-
react18版本
// 4.1 创建指定了页面容器元素的root对象 const root = ReactDOM.createRoot(container); // 4.2 渲染react元素 root.render(element) ReactDOM.createRoot(document.getElementById('root')).render(element)
-
⚠ReactDOM中的DOM全部是大写
特殊属性-类名
在react里设置类class属性时,应写className,而不是class
class属性最终要转换为DOM元素的className属性 => 标签的class属性
const element = React.createElement(
'h1',
{
className: "active"},
'Hello React!'
)
React元素
React元素也称为虚拟 DOM (virtual DOM 简写vdom) 或虚拟节点(virtual Node简写vnode)
React元素是一个普通的 JS 对象,不是真实 DOM 元素对象
虚拟DOM&真实DOM
虚拟 DOM | 真实 DOM | |
---|---|---|
差异 | 较轻的对象(属性少) | 较重的对象(属性多) |
占用内存少,创建快 | 占用内存多,创建慢 | |
关系 | 在渲染时,虚拟DOM最终都会转换为真实DOM(通过root.render(vnode)转换) |
React元素属性
{
type: , "h1"//标签名
props: {
title: '你好, React!' //n个标签属性,
children: : 'Hello React!' //字符串 / vnode / vnode的数组
},
key: 1//节点的唯一标识
}
-
标签名 => type: “h1”
-
标签属性 => props: {title: ‘你好, React!’}
-
子节点 => props: {children: ‘Hello React!’}
-
key => 节点的唯一标识
JSX
创建的子元素多后,React.createElement()的语法会变得复杂,使用JSX
const element = React.createElement( "div", { }, React.createElement("h2", { title: "北京疫情" }, "123"), React.createElement("p", { className: "active" }, "321") ); ReactDOM.createRoot(document.querySelector("#root")).render(element);
基本使用
JSX 是一种JS 的扩展语法, 用来快速创建 React 元素(虚拟DOM/虚拟节点)
- JSX形式上类似HTML标签,且标签内部可以套JS表达式
const h1 = <h1 className="active">哈哈哈</h1>
//可以用括号括起内容
const h1 = (<h1 className="active">哈哈哈</h1> )
- 浏览器无法识别JSX,需要引入babel将jsx 编译成React.createElement的形式
- babel作用
- es6 => es5
- jsx => js
- babel作用
- babel编译 JSX 语法的包为:@babel/preset-react
- 运行时编译可以直接使用babel的完整包:babel.js
JSX注意点
-
不要加引号,否则是字符串而不是JSX
let vnode = <p>aaa</p> ✅ let vnode = "<p>aaa</p>" ❌
-
必须有结束标签
<input type="text"> ❌ <input type="text" /> ✅ <span><span> ❌ <span></span> ✅
-
整个JXS只能有一个根标签
✅ let vnode = ( <p> <span>aaa</span> </p> ) ❌ let vnode = ( <p> <span>aaa</span> </p> <p>bbb</p> )
-
空标签可以自闭合
JSX使用JS表达式
jsx表达式用于显示动态数据
JSX中使用JS表达式的语法:{表达式}
-
{表达式}
使用:- 标签体文本
- 标签属性值
-
可以是js表达式,但不能是js语句
<p>---{ title.toUpperCase()}----</p>✅ <p>---{ title.toUpperCase();}----</p>❌
⚠有分号即为语句
-
基本数据中的null、undefined、布尔值在页面中不做任何显示,不会报错
-
可以是数组,会自动遍历数组进行显示
<p>{[1,2,3]}</p>
-
可以是react元素对象,但不能是非react元素的js对象
-
react元素对象可以显示
<p>{ <span>aaa</span>}</p>✅
-
js对象无法显示,会报错
例外:设置行内样式必须使用js对象
<p>{ { name:"asa",age:20}}</p>❌
-
-
style属性值必须是一个包含样式的js对象
<p style="color:'red'">aaa</p>❌ <p style={ { color:"red"}}>aaa</p>✅
-
jsx注释代码
{ /* 注释内容 */}
条件渲染
1.满足条件显示界面1,否则显示界面2
需求1: 如果loading为真显示提示loading界面, 否则显示结果页面
let loading = false
let vdom
1.if else
if (loading) {
vdom = <h2>正在加载中...</h2>
} else {
vdom = <p>结果页面</p>
}
2.三目表达式
vdom = loading ? <h2>正在加载中222...</h2> : <p>结果页面222</p>
2.只有满足条件才显示界面
不满足条件也不会报错,只是不显示界面