🚀从零开始的第一个 React 应用

268 阅读10分钟

🚀 欢迎来到 React 的世界!从零开始的第一个 React 应用

你好,未来的 React 大神!👋

你是不是刚刚创建了自己的第一个 React 项目,看到一堆文件和命令,感觉有点不知所措?别担心,这完全正常!今天,我就像你的专属向导,带你一步步揭开 React 的神秘面纱。

🤔 “我刚创建的项目里都有啥?”—— 项目文件与命令全解析

当你使用 create-react-app 这个神奇的工具初始化项目后,它已经帮你搭建好了一个专业的开发环境。我们先来看看那些最重要的命令,它们就像是你的超能力!

1. npm start - 启动你的开发服务器

  • 这是什么? 这是你最常用的命令。它会启动一个本地的开发服务器(通常在 http://localhost:3000)。
  • 有什么用? 你可以在浏览器里实时看到你的应用界面。最酷的是,当你修改代码并保存时,页面会自动刷新,让你立刻看到效果!

2. npm run build - 打包你的应用准备上线

  • 这是什么? 当你完成了应用开发,准备让全世界都看到你的杰作时,就该用这个命令了。
  • 有什么用? 它会把你的所有代码和资源打包、压缩、优化,生成一个 build 文件夹。这里面的文件就是最终可以部署到服务器上的版本,保证了最佳的加载速度和性能。

3. npm test - 运行测试

  • 这是什么? 这是一个内置的测试工具,可以帮你检查代码的正确性。
  • 有什么用? 编写测试是保证代码质量的好习惯。这个命令可以让你轻松地运行你写的测试用例。

4. npm run eject - “弹射”功能(新手请谨慎!)

  • 这是什么? 这是一个高级功能,可以让你完全控制项目的底层配置(比如 Webpack、Babel)。
  • 有什么用? create-react-app 帮你隐藏了很多复杂的配置。但如果你是高级玩家,想要深度定制,eject 可以把所有配置都暴露出来给你。但请注意:这是一个单向操作,一旦“弹射”,就回不去了! 对于初学者,我们完全不需要关心这个。

告别传统:多页应用与单页应用的演变

在深入React之前,我们先来聊聊网页应用的两种常见模式:多页应用(MPA)和单页应用(SPA)。

多页应用(MPA):传统模式

想象一下你正在浏览一个传统的网站,比如一个新闻门户。当你点击不同的新闻链接时,整个页面都会重新加载,浏览器会从服务器获取一个新的HTML文件并渲染。这就是多页应用。

特点:

  • 每个页面都是一个独立的HTML文件:这意味着每个“页面”都是一个全新的文档。
  • 页面间共同模块难以复用:比如导航栏、页脚等,可能需要在每个HTML文件中重复编写或通过服务器端模板技术引入,维护起来比较麻烦。

单页应用(SPA):现代趋势

现在,再想想你常用的社交媒体应用,比如微信朋友圈或者微博。当你切换不同的功能模块时,页面内容会快速变化,但整个浏览器页面似乎并没有刷新。这就是单页应用。

特点:

  • 整个项目只有一个HTML文件:是的,你没听错!所有的内容变化,都是在这个唯一的HTML文件中通过JavaScript动态完成的。
  • “页面”其实是代码片段:我们所看到的“不同页面”,实际上只是通过JavaScript控制,在同一个HTML文件中展示不同的代码片段。当需要切换内容时,JavaScript会动态地加载、渲染或隐藏相应的UI组件,而不是重新加载整个页面。

为什么单页应用更受欢迎?

  • 用户体验更流畅:无需整页刷新,切换内容更快,感觉就像在使用桌面应用。
  • 前后端分离:前端专注于UI展示和交互,后端专注于数据接口,开发效率更高。
  • 减少服务器压力:首次加载后,后续数据交互只需请求少量数据,而不是整个页面。

而React,正是构建这种流畅、高效单页应用的利器!

初探React项目:文件结构大揭秘

当你创建一个新的React项目时,会看到一些默认的文件和文件夹。别担心,我们来一一认识它们,就像认识新朋友一样简单!

 my-react-app/
 ├── node_modules/
 ├── public/
 │   ├── index.html
 │   ├── favicon.ico
 │   └── ...
 ├── src/
 │   ├── App.js
 │   ├── index.js
 │   └── ...
 ├── package.json
 ├── package-lock.json
 └── README.md
  • node_modules/:这个文件夹里存放着创建和运行React项目所需的所有第三方工具和库的源代码。你可以把它想象成一个巨大的工具箱,里面装满了React正常工作所需的各种“零件”。我们通常不需要直接修改这里面的文件。

  • public/:这个文件夹存放着项目的静态资源。所谓“静态资源”,就是那些不需要经过JavaScript处理就能直接被浏览器访问的文件。

    • index.html:这是你项目的“主页面”,也是整个单页应用中唯一的HTML文件。所有的React组件最终都会被“挂载”到这个HTML文件中的某个元素上。
    • favicon.icologo192.png等:这些是网站的图标和一些图片资源。
  • src/:这是你进行开发的主要目录,存放着你编写的所有React源代码。

    • index.js:这是你项目的“主入口”文件。它是整个React应用的起点,负责将你的React应用渲染到public/index.html中。
    • App.js:通常是你的根组件,代表了整个应用的主要结构。
  • package.json:这是一个非常重要的“项目配置文件”。它记录了你项目的名称、版本、依赖的第三方库(以及它们的版本)、可以运行的脚本命令等信息。当你把项目分享给别人时,他们可以通过这个文件快速安装所有依赖。

  • package-lock.json:这个文件是package.json的“详细清单”。它记录了node_modules中每个包的精确版本和它们之间的依赖关系。它的作用是确保团队中的每个成员,在安装项目依赖时,都能得到完全一致的包版本,避免因为版本不一致导致的问题。

React组件:构建用户界面的“乐高积木”

在React中,我们构建用户界面(UI)的方式就像玩乐高积木一样——把一个个小积木(组件)拼装起来,最终形成一个完整的模型(应用)。

什么是组件?

组件是React应用中独立、可复用的代码片段,它们负责渲染UI的一部分。你可以把组件想象成一个函数,接收一些输入(称为“props”,我们后面会讲到),然后返回一段描述UI的“蓝图”。

特点:

  • 可复用性:一旦你创建了一个组件,就可以在应用的任何地方多次使用它,大大提高了开发效率。
  • 独立性:每个组件都有自己的逻辑和UI,它们之间相互独立,便于管理和维护。

组件的定义

在React中,组件通常是一个JavaScript函数(或者是一个类,但函数组件在现代React中更常用)。

 // 这是一个简单的函数组件
 function WelcomeMessage() {
   return <h1>Hello, React World!</h1>;
 }

组件的命名规范

重要规则: React组件的名称首字母必须大写。这是React识别组件的关键。如果首字母是小写,React会认为它是一个普通的HTML标签。

 // 正确的组件命名
 function MyButton() { /* ... */ }
 ​
 // 错误的组件命名(React会认为是普通HTML标签)
 function myButton() { /* ... */ }

组件的调用

当你定义好一个组件后,就可以像使用HTML标签一样在你的JSX(我们马上会讲到JSX是什么)中调用它了。组件的调用方式是标签形式

 function App() {
   return (
     <div>
       <WelcomeMessage /> {/* 调用 WelcomeMessage 组件 */}
       <MyButton />       {/* 调用 MyButton 组件 */}
     </div>
   );
 }

🎨 “HTML 里写代码?”—— JSX 的魔法

你可能已经注意到,在上面的代码示例中,我们在JavaScript函数里直接写了类似HTML的代码,比如<h1>Hello, React World!</h1>。这看起来有点奇怪,但这就是React的强大之处——JSX

1. JSX:把 HTML 写在 JS 里

  • 核心思想:JSX 允许我们在 JavaScript 中像写 HTML 一样去描述用户界面长什么样。这让代码变得非常直观,你一眼就能看出组件的结构。

2. 在 “HTML” 中嵌入 JS 变量

  • 如何做? 使用花括号 {}

  • 示例

     const name = '小明';
     const element = <h1>你好, {name}!</h1>; // 会显示 “你好, 小明!”
    

    你可以把任何 JavaScript 表达式放在 {} 里,比如变量、函数调用、数学计算等。

3. 列表渲染:如何展示一堆数据?

  • 场景:假设你有一个数组,想把它展示成一个列表。

  • 方法:使用数组的 map 方法。

     const numbers = [1, 2, 3, 4, 5];
     const listItems = numbers.map((number) =>
       <li key={number.toString()}>{number}</li>
     );
     ​
     // 然后在你的组件里使用 {listItems}
    

    关键点map 会遍历数组,为每个元素返回一个 JSX 元素。注意那个 key 属性,它是 React 用来识别每个列表项的“身份证”,对于性能优化很重要!

4. 条件渲染:根据不同情况显示不同内容

  • 场景:比如用户登录了就显示“欢迎回来”,没登录就显示“请登录”。

  • 方法:在 JSX 中,我们通常使用 三元运算符 (condition ? trueValue : falseValue),而不是 if...else 语句。

     function Greeting(props) {
       const isLoggedIn = props.isLoggedIn;
       return (
         <div>
           {isLoggedIn
             ? <h1>欢迎回来!</h1>
             : <h1>请登录。</h1>
           }
         </div>
       );
     }
    

mapforEach 的区别(在JSX渲染中的应用)

你可能对JavaScript中的forEachmap方法都比较熟悉,它们都可以遍历数组。但在React的JSX渲染中,我们通常会选择map而不是forEach。这是为什么呢?

让我们看一个简单的例子:

 const arr = ['a', 'b', 'c', 'd', 'e'];
 ​
 // 使用 forEach
 // forEach 方法会遍历数组,并对每个元素执行回调函数,但它没有返回值(或者说返回 undefined)。
 // 因此,你不能直接用 forEach 来生成一个新的数组,也就不能直接在 JSX 中用于渲染。
 // const res = arr.forEach((item, index, array) => {
 //   console.log(item, index, array);
 // })
 // console.log(res); // undefined
 ​
 // 使用 map
 // map 方法也会遍历数组,但它会根据回调函数的返回值创建一个新的数组。
 // 这个新的数组正是 JSX 渲染所需要的元素列表。
 const res2 = arr.map((item, index, array) => {
   console.log(item, index, array);
   return item + '1'; // 返回一个新的元素
 })
 console.log(res2); // ["a1", "b1", "c1", "d1", "e1"]

总结:

  • forEach:用于遍历数组并执行副作用(如打印、修改外部变量),不返回新数组。
  • map:用于遍历数组并根据回调函数的返回值生成一个新的数组。这个新数组正是React在渲染列表时所期望的格式。

因此,在JSX中进行列表渲染时,我们总是使用map方法,因为它能够“映射”出新的React元素数组,供React渲染使用。

下一步学什么?

恭喜你!你已经掌握了启动一个 React 项目和 JSX 的基础知识。接下来,你可以继续探索:

  • Hooks:让函数组件拥有状态和其他 React 特性的“钩子”。
  • Router:在你的单页面应用中实现页面跳转。

希望这篇入门指南能帮你扫清初学的迷雾!记住,多动手、多尝试是学习编程最好的方法。现在就打开你的代码编辑器,开始你的 React 之旅吧!

如果你想了解更多,可以查看官方的 Create React App 文档React 文档