跟着 MDN 学 React 框架 Day 3:React 入门——核心概念与第一个应用
2026/6/16 6:25:55 网站建设 项目流程

摘要:本文是 React 入门学习的第三日记录,内容源于 MDN Web 文档的官方指南。我们将从 React 的核心理念出发,探讨它作为用户界面库的定位及其在现代 Web 开发中的用例。文章将详细解析 React 如何利用 JSX 语法在 JavaScript 中优雅地描述 HTML 结构,并通过 create-react-app 工具链,一步步带领读者从零搭建本地开发环境。最后,我们将深入剖析初始应用的结构,理解第一个组件<App/>的工作原理,并掌握 JSX 中变量和 Props 的使用技巧,为后续开发打下坚实基础。

一、你好 React:一个用于构建用户界面的库

React 的官方口号非常明确:它是一个用于构建用户界面的 JavaScript 库。理解"库"而非"框架"这一定位至关重要。框架通常提供一套完整的解决方案,强制规定代码组织、路由、数据流等方方面面的规则;而 React 则专注于做好一件事——构建 UI。它的应用范围并不局限于 Web 页面,通过与不同的渲染器结合,React 可以大展拳脚。例如,React Native 能够让开发者使用 React 语法构建原生移动应用,而 React 360 则将 React 带入了虚拟现实领域。

对于 Web 开发而言,开发者通常将 React 与 ReactDOM 协同使用。React 负责核心逻辑,而 ReactDOM 负责将 React 构建的 UI 渲染到浏览器环境中。正因如此,在日常口语化交流中,我们常将 React 与 ReactDOM 的组合统称为一个"框架",因为它们确实解决了与传统框架相同的问题。

React 的核心设计目标是最大限度地减少开发者在构建 UI 时引入的错误。它达成这一目标的关键机制就是"组件"。组件是自包含的、描述部分用户界面的逻辑代码段。它们就像乐高积木一样,可以独立开发、测试,然后组合在一起构建出复杂完整的用户界面。React 将底层的渲染、状态更新等复杂工作进行了抽象,让开发者能够更专注于 UI 设计本身,而不是繁琐的 DOM 操作。

二、用例:从微小部件到完整应用

与本模块中介绍的其他框架不同,React 并不对代码约定或文件组织结构强加严格的规则。这种灵活性赋予了团队极大的自主权,他们可以根据项目特点与自身偏好,制定最适合的约定,以任何方式采用 React。React 可以处理一个简单的按钮,也可以管理一个界面的几个部分,甚至能够承载起整个应用程序的用户界面。

尽管 React 理论上可以像 jQuery 或 Vue 那样,被"引入"到页面的某个局部来替换一小块 UI,但在实际开发中,这并不容易。React 的许多优势,尤其是其基于组件的架构和强大的状态管理能力,在用它构建整个应用时才能得到充分体现。部分引入的方式反而会增加复杂性。

此外,使用 React 通常意味着需要拥抱现代前端工具链。一个典型的例子是 JSX。JSX 是一种 JavaScript 的语法扩展,它允许我们在 JavaScript 代码中直接编写类似 HTML 的标记。但浏览器无法直接解析 JSX,必须经过一个编译步骤,将其转换为标准的 JavaScript 函数调用(即React.createElement())。在网站上直接添加一个像 Babel 这样的实时编译器会严重影响页面性能。因此,开发人员通常会在构建阶段就设置好这类工具,提前将 JSX 编译成高效的 JavaScript 代码。这个过程对工具链的要求虽然较高,但带来的开发体验和运行效率提升是值得学习的。

本文将聚焦于一个最主流的用例:利用 Facebook 官方提供的 create-react-app 脚手架工具,创建一个用于渲染整个应用用户界面的 React 项目。

三、React 如何使用 JavaScript?——JSX 的魅力

React 的许多设计模式都深度运用了现代 JavaScript 的特性,但与原生 JavaScript 最直观的区别在于 JSX 语法的使用。JSX 是 JavaScript 和 XML 的结合体,它让类似 HTML 的代码能够与 JavaScript 逻辑共存,极大地提升了代码的可读性和编写效率。

一个简单的 JSX 表达式如下:

const heading = <h1>Mozilla Developer Network</h1>;

这段代码不是字符串,也不是 HTML,它就是 JSX。React 可以使用这个heading常量直接在应用中渲染一个<h1>标签。如果出于语义化考虑,我们想将这个标题包裹在<header>标签内,JSX 允许我们像写 HTML 一样自然地进行元素嵌套:

const header = ( <header> <h1>Mozilla Developer Network</h1> </header> );

请注意,代码外层的括号并非 JSX 语法的一部分,它只是一个纯粹的分隔符,用于向开发者和格式化工具明确表示,括号内的多行代码属于同一个表达式。这在编写多行 JSX 时非常有用,避免了因为缩进问题导致的歧义。

浏览器无法直接读取并理解 JSX。上面的header表达式在经过 Babel 或 Parcel 等编译工具的转换后,会变成如下形式:

constheader=React.createElement("header",null,React.createElement("h1",null,"Mozilla Developer Network"));

我们当然可以完全跳过编译步骤,直接使用React.createElement()来手写 UI,但这将完全丧失 JSX 带来的声明式、直观的编写优势,代码会变得异常复杂且难以阅读。编译是开发流程中的一个额外环节,但 React 社区普遍认为,JSX 带来的可读性收益远超其成本。流行的工具链已经将 JSX 到 JavaScript 的编译集成进了设置过程,除非有特殊需求,开发者无需手动配置。

对于 JSX 这种混合特性,一些开发者觉得直观,另一些可能觉得混乱。但不可否认的是,一旦熟悉它,构建用户界面的速度和直观性都会显著提升,同时也能让团队成员更轻松地理解代码库的结构和意图。

四、设置你的第一个 React 应用:使用 create-react-app

有多种方式可以将 React 集成到项目中,但 create-react-app 命令行工具是官方推荐的最便捷的起点。它通过安装一系列精心配置的软件包并生成一套标准化的项目文件结构,极大地加速了 React 应用的启动过程,让开发者能将更多时间花在业务逻辑构建上,而非环境配置。

要求

在开始之前,你需要确保电脑上安装了 Node.js,推荐使用长期支持(LTS)版本。Node.js 会附带 npm(包管理器)和 npx(包运行器)。你也可以选择 Yarn 作为替代的包管理器,但本教程假设使用 npm。如果你使用的是 Windows 系统,为了能顺利运行本教程中的终端命令,建议安装 Gitbash 或 Linux 的 Windows 子系统,以获得与 Unix/macOS 终端一致的操作体验。

还需要注意的是,React 和 ReactDOM 生成的应用程序默认支持一组相当现代的浏览器,通过一些 polyfill 可以兼容到 IE9+。在进行学习时,建议使用 Firefox、Safari 或 Chrome 等现代浏览器以获得最佳体验。

初始化你的应用

create-react-app 命令接受一个参数,即你为应用设定的名称。它会创建一个同名的文件夹,并在其中生成所有必需的文件。请打开命令行终端,进入你希望存放项目的文件夹,然后执行以下命令:

npx create-react-app moz-todo-react

这条命令会创建一个名为moz-todo-react的文件夹,并自动完成以下几项关键工作:

  • 为你的应用安装所有必需的 npm 包。
  • 写入启动、构建、测试等 React 应用所需的脚本。
  • 创建一系列结构化的子文件夹和文件,奠定应用程序的基础架构。
  • 如果你的电脑上安装了 git,它会自动初始化一个 Git 仓库。

如果你同时安装了 Yarn 和 npm,但希望强制使用 npm,可以在命令后加上--use-npm参数:

npx create-react-app moz-todo-react --use-npm

执行过程可能需要几分钟,终端会显示一些状态信息。命令执行完毕后,进入项目文件夹并启动开发服务器:

cdmoz-todo-reactnpmstart

该命令会启动一个本地开发服务器,通常在http://localhost:3000地址上运行,并自动在默认浏览器中打开这个地址。如果一切顺利,你会看到一个 React 欢迎页面。

五、探索第一个 React 组件 —<App/>

create-react-app 生成的项目结构中最核心的源码目录是src。其中,src/App.js文件包含了我们接触到的第一个,也是最重要的根组件App。打开它,其内容如下:

importReactfrom'react';importlogofrom'./logo.svg';import'./App.css';functionApp(){return(<div className="App"><header className="App-header"><img src={logo}className="App-logo"alt="logo"/><p>Edit<code>src/App.js</code>and save to reload.</p><a className="App-link"href="https://reactjs.org"target="_blank"rel="noopener noreferrer">Learn React</a></header></div>);}exportdefaultApp;

这个文件清晰地展示了 React 组件的三个典型组成部分:顶部的导入语句,中间的函数式组件定义,以及底部的导出语句。

导入语句

importReactfrom'react';importlogofrom'./logo.svg';import'./App.css';

这三行导入分别代表了三种不同的模块导入场景。第一行从名为react的 npm 包中导入 React 核心对象。这是任何包含 JSX 的模块所必需的,因为 JSX 最终会被转换为React.createElement调用。第二行导入一个本地的 SVG 文件,并将其赋值给logo变量。以./开头的路径表明这是一个相对于当前文件的本地模块。第三行直接导入一个 CSS 文件,这种语法不将其赋给任何变量,它是 webpack 这类模块打包器提供的特性,能将 CSS 注入到应用中。

App 组件

组件的主体是一个名为App的普通 JavaScript 函数。请注意,React 的组件名必须使用帕斯卡命名法(PascalCase),即首字母大写,如AppUserProfile,以便在 JSX 中与普通的 HTML 标签(如<div>)区分开来。如果函数名是小写的,React 会将其视为一个普通的 HTML 元素,从而导致错误。

该函数返回一个 JSX 表达式,这个表达式精确地描述了浏览器最终要渲染的 DOM 结构。仔细观察这个 JSX,你会发现一些与标准 HTML 不同的地方,例如<div>标签的属性是className而非class。这是因为class是 JavaScript 的保留关键字,JSX 作为 JavaScript 的扩展,为了避免冲突,便使用了className。类似地,许多 HTML 属性在 JSX 中都采用了驼峰式命名。

现在,我们可以尝试对组件进行简单修改。将<p>标签的内容改为 “Hello, world!”,然后保存文件。浏览器页面会立即自动刷新,显示新的文本。接着,删除整个<a>标签并保存,页面上 “Learn React” 的链接也会随之消失。这种热更新机制是 React 开发体验中非常重要的一环。

修改后的App组件如下:

functionApp(){return(<div className="App"><header className="App-header"><img src={logo}className="App-logo"alt="logo"/><p>Hello,World!</p></header></div>);}

Export 语句

文件最底部的export default App语句是关键。它使得App组件能够被其他 JavaScript 模块导入和使用,是 React 组件化和模块化的基石。没有它,App组件将是一个私有的函数,无法在外部使用。

六、审查入口文件:初识渲染机制

现在让我们打开src/index.js文件,它是整个 React 应用的入口点。初始内容如下:

importReactfrom'react';importReactDOMfrom'react-dom';import'./index.css';importAppfrom'./App';import*asserviceWorkerfrom'./serviceWorker';ReactDOM.render(<App/>,document.getElementById('root'));serviceWorker.unregister();

App.js类似,文件顶部进行了必要的模块导入。关键点在于它从./App路径导入了我们刚刚创建的App组件。正是因为App.js底部有export default App,这里的import App from './App'才能成功执行。

最核心的一行代码是:

ReactDOM.render(<App/>,document.getElementById('root'));

ReactDOM.render()函数接收两个参数:

  • 要渲染的 React 元素:这里使用的是<App />,它是一个 JSX 标签,代表我们的根组件。注意,像<App />这样的自闭合标签是必需的,缺少闭合斜杠会导致错误。
  • 目标 DOM 容器:这里通过原生 JavaScript 方法获取了 ID 为root的 DOM 元素。这个元素可以在public/index.html文件中找到,它是 React 应用挂载并渲染整个组件树的根节点。

整行代码的含义就是:React,请获取App组件所描述的 UI,并将其渲染到 HTML 页面中 ID 为root<div>容器里。关于serviceWorker的代码用于实现离线缓存等 PWA 特性,不在本入门讨论范围内,可以暂时忽略或删除。

七、变量与 Props:让组件动起来

现在,我们将学习如何利用 JavaScript 的变量和 React 特有的 Props 机制,让组件处理动态数据,使其更具灵活性和复用性。

JSX 中的变量

回到App.js,请看这行代码:

<img src={logo} className="App-logo" alt="logo" />

这里,src属性的值被包裹在一对大括号{}中。在 JSX 语法中,大括号是通往 JavaScript 世界的"传送门"。任何有效的 JavaScript 表达式都可以放在大括号内,React 会计算其值并嵌入到生成的 HTML 中。这里的{logo}告诉 React 去查找第二行导入的logo变量,并将其值(即 SVG 文件的路径)作为src属性的值。

我们可以定义自己的变量。在App函数的return语句之前,添加一行const subject = 'React';。然后将<p>标签中的文本修改为使用该变量:

function App() { const subject = "React"; return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p>Hello, {subject}!</p> </header> </div> ); }

保存后,浏览器会显示 “Hello, React!”。这就是在 JSX 中使用变量的基本方式。

组件 Props

变量非常方便,但它定义在组件内部,是静态的。如何从外部向组件传递数据呢?这就需要用到 Props。Props(Properties 的缩写)是传入 React 组件的、只读的参数集合。它的用法和编写 HTML 属性非常相似。

首先,我们在index.js中为<App />组件传入一个名为subject的 prop:

ReactDOM.render(<App subject="Clarice" />, document.getElementById('root'));

现在,App组件就收到了一个名为subject、值为"Clarice"的数据。为了在组件内部访问它,我们需要修改App函数的签名,让它接收一个props参数。

function App(props) { const subject = props.subject; return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p>Hello, {subject}!</p> </header> </div> ); }

所有传递给组件的 props 都会被 React 自动收集到一个名为props的对象中,该对象会作为函数的第一个参数传入。props.subject的值正是我们在index.js中设置的"Clarice"。现在,页面上就会渲染出 “Hello, Clarice!”。如果我们回到index.js修改subject的值为其他字符串,页面文本也会随之改变。这展示了 Props 的核心作用:让父组件(此处是index.js中的逻辑)能够配置和传递数据给子组件(App组件),实现了组件的动态化和可复用性。

总结

本文通过 MDN 的官方指南,系统性地入门了 React。我们首先理解了 React 作为一个专注 UI 的库的定位,及其通过组件化来最小化开发错误的目标。接着,我们分析了 React 的用例,它更适合构建完整的应用,并通常需要现代化的工具链支持。文章的核心部分深入探讨了 JSX 语法,它是 React 与 JavaScript 结合的关键,通过编译过程实现了声明式的 UI 构建。随后,我们通过 create-react-app 成功搭建了第一个 React 应用环境,并剖析了其目录结构。我们重点研究了App组件的内部构造,包括导入/导出机制、PascalCase 命名法和 JSX 中特殊的属性名。在入口文件index.js中,我们了解了ReactDOM.render()如何将根组件挂载到 DOM。最后,我们掌握了在 JSX 中使用变量的方法,并学习了 Props 这一核心机制,实现了父组件向子组件传递数据的功能。

回顾一下本次学习的关键点:

  • React 组件通过import引入依赖,并通过export default暴露自身。
  • 组件名称必须使用帕斯卡命名法(PascalCase)。
  • 在 JSX 中,通过将变量包裹在{}中来访问其值,如{variable}
  • 部分 HTML 属性在 JSX 中名称不同,如class写作className,属性名遵循驼峰命名法。
  • Props(属性)像 HTML 属性一样写在组件标签上,所有 props 会被打包成一个对象作为组件函数的第一个参数,用于从父组件向子组件传递数据。

到此,React 的基础知识框架已经建立。掌握了这些,我们就可以在下一篇文章中开始动手创建第一个真正的交互式应用——一个任务清单程序,继续我们的 React 学习之旅。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询