你好React
你好React
让我们从一个“hello world”的 React 应用程序开始,使用纯 JavaScript:
我们从两个文件开始:一个 index.html 文件,包含一个基本的 HTML 文档,以及一个 index.js 文件,包含一个最小的 React 应用程序。
当我们运行这段代码时,我们得到了一个展示文本“Hello World!”的段落。
这里有很多要探讨的内容。我们将逐节进行。如果你愿意的话,我鼓励你花几分钟来仔细研究这个例子。看看你能通过一点侦探工作发现什么?!
1. 导入依赖项
文件的顶部有两个导入语句,使用本地 JavaScript 模块系统。我们正在从 react 依赖项中导入核心 React 库,以及从 react-dom 中导入 createRoot 函数。
如果你在想为什么有两个独立的包,那是因为 React 本身是“平台无关”的。我们有核心 react 包,然后有不同的平台专用渲染器:
react-dom
使用于Webreact-native
适用于移动端(iOS / Android)或桌面端(Windows / macOS)应用程序react-three-fiber
用于使用 WebGL 和 Three.js 制作 3D 场景
每个平台都有自己的“原始组件”,这是我们用来创建用户界面的内置元素集合。在网页上,原始组件是像 <div> 、 <p> 和 <button> 这样的 HTML 元素。相比之下,React Native 没有 div,而是有 Text 、 View 和 Pressable 。当使用 react-three-fiber 时,情况变得更加复杂,原始组件是灯光、几何体、材质和相机等东西。 .
所有这些平台将使用相同的核心 React 框架,该框架来自 react 包。但是,当涉及到将所有业务逻辑转化为用户界面时,我们需要适合我们平台的正确绑定。
这实际上是一件很棒的事情,因为这意味着你在学习 React 时所掌握的技能也可以用于构建移动应用程序或 3D 界面,如果这正是你的兴趣或职业发展的方向!
“DOM”到底是什么?
DOM 是构成实时网站/ web 应用程序的活的、呼吸的结构。当我们访问一个网站时,浏览器将静态 HTML 转换为 DOM。
用一个类比来说:HTML 是特定汽车的蓝图,而 DOM 就是那辆在城市里穿行的汽车。
这是另一种看待它的方法:
- 当你右键点击并选择“查看源代码”时,你查看的是 HTML,一个描述将要构建内容的静态文档。
- 当你右键单击并“检查元素”以打开元素面板时,你正在与 DOM 互动。你可以更改属性并观察 UI 随之更新。
当我们使用像 React 这样的工具时,它通过 JavaScript 与 DOM 进行交互。它将根据需要创建、更新和删除 DOM 元素。
如果你想知道,DOM 代表文档对象模型(Document Object Model)。
2. 创建一个 React 元素
接下来在我们的微型应用中,我们有以下代码:
React.createElement 是一个接受 3 个或更多参数的函数:
- 要创建的元素类型。
- 我们希望这个元素具有的属性。
- 元素的内容。如果元素应该是空的,我们可以省略这一部分。
该函数返回一个“React 元素”。React 元素是普通的 JavaScript 对象。如果我们用 console.log(element) 检查它,我们会看到类似这样的东西:
这个 JavaScript 对象是一个假设的段落标签的描述,ID 为 hello ,包含文本 "Hello World!" 。这些信息将用于构建我们在浏览器中可以看到的实际段落。
在本课程的后面,我们将学习 key 和 ref 。最后两个属性 _owner 和 _store 是供 React 内部使用的,可以安全地忽略*。
DOM 层次结构
DOM 像树一样组织。就像家谱一样,单个元素可以有父母、祖父母、兄弟姐妹和孩子。
例如,考虑这个文件:
<main> 元素:
- 以 <body> 作为其父级。
- 只有一个子元素,即 <p> 元素。
- 有唯一的兄弟姐妹<footer>。
这种层次结构是网络的重要组成部分。我们在 CSS 中引用它,当编写选择器时如下所示:
React 同样采用了这种模型。正如我们所见,React 元素可以指定“子元素”。我们使用相同的语言,因为 React 元素的结构与 DOM 元素的结构一样形成层次关系。
3. 呈现应用程序
我们已经到达了最后几行代码:
document.querySelector 是一个有用的函数,可以让我们捕获对现有 DOM 元素的引用。
这在这种情况下起作用是因为我们的 index.html 文件包含以下元素:
这个元素将是我们应用程序的容器。当我们渲染我们的 React 应用程序时,它将在这个容器中创建并附加新的 DOM 元素。
使用 react-dom 的 createRoot 函数,我们指定该元素应该是我们应用程序的根。最后,使用 root.render(element) 渲染应用程序。
您可以将 render 函数视为一个将 React 元素转换为 DOM 节点的机器。在这种情况下,我们的 React 元素描述了一个段落标签,带有 ID 和一些文本。 render 将把该描述转换为以下 DOM 结构:
创建了那个 DOM 元素后,它会将其添加到指定的根节点的页面中。实质上,这段代码使用基于 JavaScript 的某些 HTML 描述,并利用它生成实际的 DOM 节点。
这可能看起来是创建段落的一种非常复杂的方法!但是,正如我们在本课程中将要学习的,真正的魔法发生在变化的时候。✨
这最近发生了变化!
如果您读过其他 React 教程,您可能见过类似这样的内容:
这是在版本 17 及之前如何渲染 React 应用程序的。在版本 18 中(于 2022 年 3 月发布),API 更改为上面显示的 createRoot 和 render 组合。
在本课程的某些视频中,你会看到这个 API 的片段,这些片段是在我将 React 升级到最新版本之前录制的。
构建系统
在我们这一课中看到的游乐场有点奇怪:没有 script 标签!
当我们没有 <script src="/index.js"></script> 时,我们的代码究竟是如何运行的?
关于 React 需要知道的事情是,它是在一个构建系统中使用的。我们处理的文件是这个系统的输入。
我们可以通过检查“结果(Result)” <iframe> 中的 HTML 来亲身体验这一点:
index.js 文件以及依赖项(React、React DOM)被打包到像 2.61b71a6f1.chunk.js 这样的神秘命名文件中,并且一个 <script> 标签被动态注入到 HTML 中。
我并不指望你理解所有这些标记是什么,或者它为什么存在。现在要知道的重要事情是,有一个活跃的过程可以转换我们编写的文件。
如果你没有使用过其他 JS 框架,这可能对你来说显得过于复杂。我们为什么不能像在使用 jQuery 和其他库时那样,使用 <script> 标签自己添加代码呢?
这有几个原因:
- 正如我们将要了解的,JSX 需要被编译成 JS
- 它使生活质量得以改善,例如能够使用最新的 JavaScript 特性
- 这对良好的性能是必要的,因为 React 应用程序通常有数百个甚至数千个需要捆绑在一起的 JS 文件。
我们将在“行业工具(后续章节)”参考模块中更多地了解构建系统。