React全家桶笔记(一):React入门 — 虚拟DOM与JSX
本系列笔记基于尚硅谷React全家桶教程整理,适合初学者系统学习React,也可作为面试复习参考。 📺 对应视频:P1 - P7
一、React 简介(P1)
1.1 React 是什么?
React 是 Facebook 开发并开源的一个用于构建 用户界面的 JavaScript 库。
注意关键词:
- 构建 用户界面 — React 只关注视图层(View),不是一个完整的 MVC 框架
- JavaScript 库 — 不是框架,是库。框架是全套解决方案,库是解决特定问题的工具
1.2 为什么要学 React?
- 原生 JS 操作 DOM 繁琐、效率低(DOM-API 操作 UI)
- 使用 JS 直接操作 DOM,浏览器会进行大量的重绘重排
- 原生 JS 没有组件化编码方案,代码复用率低
1.3 React 的特点
- 组件化模式,声明式编码,提高开发效率及组件复用率
- 在 React Native 中可以用 React 语法进行移动端开发
- 使用虚拟 DOM + 优秀的 Diffing 算法,尽量减少与真实 DOM 的交互
🔗 概念扩展:声明式 vs 命令式
- 命令式:告诉计算机"怎么做"(jQuery 就是典型的命令式)
- 声明式:告诉计算机"要什么"(React/Vue 都是声明式,你描述 UI 长什么样,框架帮你实现)
二、Hello React 案例(P2)
2.1 相关 JS 库
react.development.js — React 核心库
react-dom.development.js — React 操作 DOM 的扩展库
babel.min.js — 将 JSX 转为 JS 的编译器
引入顺序很重要:先引 react 核心库,再引 react-dom。因为 react-dom 依赖 react 核心库。
2.2 第一个 React 程序
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello React</title>
</head>
<body>
<!-- 准备一个容器 -->
<div id="test"></div>
<!-- 引入核心库,必须在 react-dom 之前 -->
<script src="react.development.js"></script>
<script src="react-dom.development.js"></script>
<script src="babel.min.js"></script>
<!-- type 必须写 text/babel,表示这里写的是 JSX -->
<script type="text/babel">
// 1. 创建虚拟 DOM
const VDOM = <h1>Hello, React</h1>
// 2. 渲染虚拟 DOM 到页面
ReactDOM.render(VDOM, document.getElementById('test'))
</script>
</body>
</html>
⚠️ 易错点:
<script>标签的type必须写text/babel,否则浏览器会把 JSX 当作普通 JS 解析而报错。
三、虚拟 DOM 的两种创建方式(P3)
3.1 方式一:JSX 创建(推荐)
// JSX 方式 — 简洁直观
const VDOM = (
<h1 id="title">
<span>Hello, React</span>
</h1>
)
3.2 方式二:JS 创建(不推荐)
// 纯 JS 方式 — React.createElement(标签名, 属性, 内容)
const VDOM = React.createElement('h1', { id: 'title' },
React.createElement('span', {}, 'Hello, React')
)
对比结论:
- JSX 是
React.createElement()的语法糖 - 当结构嵌套复杂时,纯 JS 写法会非常繁琐
- JSX 更贴近 HTML 的写法,开发体验更好
- Babel 会把 JSX 编译成
React.createElement()调用
🔗 概念扩展:语法糖(Syntactic Sugar) 指计算机语言中添加的某种语法,对语言的功能没有影响,但更方便程序员使用。JSX 就是
React.createElement()的语法糖,本质上做的是同一件事。
四、虚拟 DOM 与真实 DOM(P4)
4.1 虚拟 DOM 本质
const VDOM = <h1>Hello</h1>
console.log(VDOM) // 输出一个普通的 JS 对象
console.log(typeof VDOM) // "object"
关键认知:
- 虚拟 DOM 本质是一个普通的 JavaScript 对象(Object)
- 虚拟 DOM 比真实 DOM "轻",因为虚拟 DOM 是 React 内部在用,不需要真实 DOM 上那么多属性
- 虚拟 DOM 最终会被 React 转化为真实 DOM,渲染到页面上
4.2 虚拟 DOM vs 真实 DOM
虚拟 DOM:
{ type: 'h1', props: { id: 'title', children: 'Hello' } }
→ 属性很少,很"轻"
真实 DOM:
一个 <h1> 元素上有几百个属性和方法
→ 非常"重"
🎯 面试高频:虚拟 DOM 的工作流程
- 数据变化时,React 用新数据生成新的虚拟 DOM 树
- 将新旧两棵虚拟 DOM 树进行 Diff 比较
- 找出差异部分,只更新差异部分到真实 DOM
- 这就是 React 高效的核心原因 — 最小化 DOM 操作
五、JSX 语法规则(P5-P6)
JSX 全称 JavaScript XML,是 React 定义的一种类似于 XML 的 JS 扩展语法:JS + XML。
5.1 核心语法规则
规则1:定义虚拟 DOM 时,不要写引号
// ✅ 正确
const VDOM = <h1>Hello</h1>
// ❌ 错误 — 加了引号就变成字符串了
const VDOM = '<h1>Hello</h1>'
规则2:标签中混入 JS 表达式时,用花括号 {}
const name = 'React'
const VDOM = <h1>Hello, {name}</h1>
规则3:样式的类名用 className ,不用 class
// ✅ 正确
<div className="title">Hello</div>
// ❌ 错误 — class 是 JS 的保留字
<div class="title">Hello</div>
规则4:内联样式用 style={{key: value}} 的形式
// 注意:外层 {} 表示要写 JS 表达式,内层 {} 是一个对象
// CSS 属性名用小驼峰命名
<div style={{color: 'white', fontSize: '20px'}}>Hello</div>
规则5:只能有一个根标签
// ✅ 正确
const VDOM = (
<div>
<h1>标题</h1>
<p>内容</p>
</div>
)
// ❌ 错误 — 两个根标签
const VDOM = (
<h1>标题</h1>
<p>内容</p>
)
规则6:标签必须闭合
// ✅ 自闭合
<input type="text" />
// ✅ 成对闭合
<div></div>
// ❌ 错误
<input type="text">
规则7:标签首字母
- 小写字母开头:React 会将其转为 HTML 同名元素。如果 HTML 中没有该标签,就报错
- 大写字母开头:React 会去渲染对应的组件。如果组件未定义,就报错
<div>这是 HTML 标签</div>
<MyComponent>这是 React 组件</MyComponent>
5.2 JSX 小练习 — 动态渲染列表
const data = ['Angular', 'React', 'Vue']
const VDOM = (
<div>
<h1>前端框架列表</h1>
<ul>
{
data.map((item, index) => {
return <li key={index}>{item}</li>
})
}
</ul>
</div>
)
ReactDOM.render(VDOM, document.getElementById('test'))
⚠️ 易错点:表达式 vs 语句
- 表达式:会产生一个值,可以放在任何需要值的地方。如
a、a+b、fn(1)、arr.map()、function test(){} - 语句:控制代码走向,不会产生值。如
if(){}、for(){}、switch(){} - JSX 的
{}中只能写表达式,不能写语句!
🎯 面试高频:为什么遍历列表要加 key? key 是虚拟 DOM 的标识,在 Diffing 算法中起关键作用。当数据变化时,React 会根据 key 来判断哪些元素是新增的、哪些是修改的、哪些是删除的,从而最小化 DOM 操作。(后续 Diffing 算法章节会详细展开)
六、组件与模块(P7)
6.1 模块
- 定义:向外提供特定功能的 JS 程序,一般就是一个 JS 文件
- 为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂
- 作用:复用 JS,简化 JS 的编写,提高 JS 运行效率
- 模块化:当应用的 JS 都以模块来编写,这个应用就是一个模块化的应用
6.2 组件
- 定义:用来实现局部功能效果的代码和资源的集合(HTML/CSS/JS/图片等)
- 为什么要用组件:一个界面的功能更复杂
- 作用:复用编码,简化项目编码,提高运行效率
- 组件化:当应用是以多组件的方式实现,这个应用就是一个组件化的应用
6.3 模块 vs 组件
模块:侧重于 JS 层面的功能拆分
→ 一个 utils.js、一个 api.js 就是一个模块
组件:侧重于 UI 层面的功能拆分
→ 一个 Header、一个 Footer 就是一个组件
→ 组件包含了 HTML + CSS + JS + 图片等所有资源
🔗 概念扩展:组件化开发的思维方式 拿到一个页面设计稿,第一步不是写代码,而是拆分组件:
- 哪些部分可以抽成独立组件?
- 组件之间是什么关系?(父子、兄弟)
- 数据应该放在哪个组件中? 这种"自顶向下拆分"的思维方式,是 React 开发的核心。
本章知识图谱
React 入门
├── React 是什么 → 构建 UI 的 JS 库(非框架)
├── 虚拟 DOM
│ ├── 本质:JS 对象(轻量级的 DOM 描述)
│ ├── 创建方式:JSX(语法糖)/ React.createElement(原始)
│ └── 工作流程:数据变化 → 新虚拟DOM → Diff对比 → 最小化更新真实DOM
├── JSX 语法
│ ├── 不加引号
│ ├── {} 中写 JS 表达式(非语句)
│ ├── className 代替 class
│ ├── style={{}} 双花括号 + 小驼峰
│ ├── 单根标签
│ ├── 标签必须闭合
│ └── 首字母大小写决定是 HTML 标签还是组件
└── 组件与模块
├── 模块 → JS 功能拆分
└── 组件 → UI 功能拆分(HTML+CSS+JS+资源)
📌 下一篇:[React全家桶笔记(二):React组件核心 — State、Props、Refs] 我们将深入 React 组件的三大核心属性,这是 React 开发的基石。