从零开始学 React:用搭积木的方式构建你的第一个网页!

引言

适合人群 :完全没接触过 React 的前端小白
学习目标:理解 React 的核心思想,掌握 JSX、组件化、状态管理等基本概念,并能运行自己的第一个 React 应用!


第一章:React 是什么?为什么我们要学它?

在传统的网页开发中,我们写 HTML 搭结构,写 CSS 调样式,再用 JavaScript 加点交互。这种方式对于小页面没问题,但一旦项目变大,代码就会变得混乱、难以维护。

React 是由 Facebook(现 Meta)推出的一个用于构建用户界面的 JavaScript 库。它的最大特点就是:

"一切皆组件"

想象一下乐高积木:每个小块都有固定形状和功能,你可以把它们拼成房子、汽车、飞船......

React 就是让你用"组件"这种"智能积木"来搭建网页!


第二章:如何初始化一个 React 项目?

现代前端工程离不开构建工具。目前最流行、速度最快的工具之一是 Vite。它由 Vue 作者尤雨溪开发,但对 React 支持极佳。

初始化步骤(一字不差照做即可):

打开终端(Mac/Linux 用 Terminal,Windows 用 PowerShell 或 CMD),输入:

复制代码
npm init vite

然后你会看到一系列提示:

  1. Project name: 输入项目名,比如 my-first-react-app
  2. Select a framework: 选择 react
  3. Select a variant: 选择 javascript(因为我们还没学 TypeScript)

完成后,进入项目目录并安装依赖:

复制代码
cd my-first-react-app
npm install

最后启动开发服务器:

复制代码
npm run dev

你会看到类似这样的输出:

复制代码
  VITE v5.0.0  ready in 300 ms

  ➜  Local:   http://localhost:5173/

打开浏览器访问 http://localhost:5173,恭喜!你已经成功运行了第一个 React 应用!🎉

完整项目链接:lesson_zp/react/jsx/jsx-demo:AI + 全栈学习仓库

项目结构如图:


第三章:项目文件结构初探

一个典型的 Vite + React 项目包含以下关键文件,其中 App2.jsx 是我们另外创建的:

  • main.jsx:程序入口文件
  • index.css:全局样式重置
  • App.jsxApp2.jsx:两个不同的根组件示例
  • App.css:组件专属样式
  • readme.md:知识点说明文档

接下来,我们将逐个深入分析这些文件,并配上详细解释。


第四章:入口文件 main.jsx ------ 把组件"挂"到网页上

javascript 复制代码
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App2 from './App2.jsx'
import App from './App.jsx'

// 组件 = UI + 交互 + 状态
// 组件化开发
// 挂载根组件
// react 一开始就是组件思想,非常的纯粹

createRoot(document.getElementById('root')).render(
  <StrictMode>
    {/* <App2 /> */}
    <App />
  </StrictMode>,
)

逐行解析:

  • import { StrictMode } from 'react'

    引入 React 的严格模式,帮助你在开发时发现潜在问题(比如废弃 API 的使用)。

  • import { createRoot } from 'react-dom/client'

    这是 React 18 引入的新渲染方式。createRoot 创建一个"根容器",用于管理整个应用的渲染。

  • document.getElementById('root')

    找到 index.html 中的 <div id="root"></div> ------ 这是 React 应用的"舞台"。

  • import App from './App2.jsx'import App1 from './App.jsx'

    同时引入了两个根组件。注意:变量名可以任意取,这里 App1 实际指向 App.jsx

  • <StrictMode> ... </StrictMode>

    包裹整个应用,开启开发辅助检查。

  • {/* <App /> */}

    这是 JSX 的注释语法(类似 HTML 的 <!-- -->,但在 {} 内)。

  • <App1 />

    当前实际渲染的是 App.jsx 的内容(因为 App1 是它的别名)。

关键知识点

  • React 应用必须通过 createRoot(...).render(...) 挂载到 DOM 节点上。
  • 你可以在 main.jsx 中自由切换使用 App2(静态页面)或 App(动态页面)。

第五章:静态页面示例 ------ App2.jsx(组件化思维)

javascript 复制代码
function JuejinHeader() {
  // jsx 最外层只能有一个元素,需要一个包裹元素,例如一个div
  return (
    <div>
      <header>
        <h1>掘金首页</h1>
      </header>
    </div>
  )
}

const Ariticles = () => {
  return (
    <div>
      <section>
        <h2>文章列表</h2>
        <ul>
          <li>文章1</li>
          <li>文章2</li>
          <li>文章3</li>
        </ul>
      </section>
    </div>
  )
}

const Checkin = () => {
  return (
    <div>
      <section>
        <h2>签到组件</h2>
        <button>签到</button>
      </section>
    </div>
  )
}

const HotArticles = () => {
  return (
    <div>
      <section>
        <h2>热门文章</h2>
        <ul>
          <li>热门文章1</li>
          <li>热门文章2</li>
          <li>热门文章3</li>
        </ul>
      </section>
    </div>
  )
}

function App() {
  // 子组件们(JuejinHeader、Ariticles、Checkin、HotArticles)构成父组件(App)
  return (
    <div>
      {/* <h1>Hello <b>React</b></h1> */}
      {/* 头部组件 */}
      <JuejinHeader />
      <main>
        {/* 组件也和html一样申明,自定义组件 */}
        {/* 组件化让我们像搭积木一样组合成页面 */}
        <Ariticles />
        <aside>
          <Checkin />
          <HotArticles />
        </aside>
      </main>
    </div>
  )
}

// 导出组件
export default App

核心概念详解:

1. 函数就是组件

在 React 中,任何返回 JSX 的函数就是一个组件 。你可以用 function 声明,也可以用箭头函数(const MyComponent = () => {...})。

✅ 规则:组件名必须以大写字母开头(如 JuejinHeader),否则 React 会把它当作普通 HTML 标签!

2. JSX 最外层只能有一个根元素

每个组件的 return 必须是一个单一的 JSX 元素。如果想返回多个兄弟元素,必须用 <div><section><>...</>(Fragment)包裹。

3. 组件组合 = 页面搭建

App 组件没有写具体 UI,而是直接"调用"了四个子组件:

  • <JuejinHeader />:头部
  • <Ariticles />:主内容区
  • <Checkin /><HotArticles />:侧边栏

这就像:

  • 你设计一栋楼(App
  • 让工人分别建厨房、卧室、客厅(子组件)
  • 最后拼在一起

优势 :每个组件独立开发、测试、复用。比如 Checkin 组件以后可以用在其他页面!

4. JSX 注释语法

在 JSX 中写注释要用 {/* 注释内容 */},不能用 //<!-- -->


第六章:动态交互页面 ------ App.jsx(状态与响应式)

javascript 复制代码
// 为什么函数就是组件? 因为函数将JSX + 逻辑 封装起来了,这就是组件
// JSX 负责UI

// 样式可在外面引入
import './App.css';

// 引入响应式
// use使用 state数据状态 useState 使用状态
import { createElement, useState } from 'react';

function App() {
  // 组件的数据业务逻辑、交互等可以写在前面
  // const name = 'React';
  // useState 返回一个数组,数组第一个元素是状态值,第二个元素是修改状态值的函数
  const [name, setName] = useState('React');
  const [todos, seTodos] = useState([
    { id:1, title:"学习React", done:false },
    { id:2, title:"学习Node", done:false },
    { id:3, title:"学习Vue", done:false },
  ])
  const [isLoggedIn, setisLoggedIn] = useState(false)

  const toggleLogin = () => {
    setisLoggedIn(!isLoggedIn)
  };

  // 语法糖,主要是简化模板开发,提升代码的可读性
  // 所以这就是一段JSX,可作为一个子组件放在UI中运行,但由于是const申明,所以用{}包裹
  // 此处用的就是createElement的语法糖
  const element = <h2>JSX 是React中用于描述用户界面的语法拓展</h2>
  // 与上句效果相同,但此句用了createElement
  const element2 = createElement('h2', null, 'JSX 是React中用于描述用户界面的语法拓展2')

  setTimeout(() => {
    setName('React1');
  }, 2000);

  return (
    // 返回JSX,即组件的UI结构
    // 在JSX中 {} 内可以写js表达式或者变量,等同于vue模板语法中的 {{ }}
    // <h1>Hello <span>{name}!</span></h1>
    // <> </> 是文档碎片标签,用来作为最外层的包裹元素
    <>
      {element}
      {element2}
      {/* JSX的js中,class是关键字,所以不能用,要用className代替 */}
      <h1>Hello <span className="title">{name}!</span></h1>
      {
        todos.length > 0 ? (
          <ul>
            {
              // 原生JS react能不用新语法就不用
              // xml in js = jsx
              // 需要加key属性,帮助react识别每个元素,提升渲染性能
              todos.map((todo) => (
                <li key={todo.id}>
                  {todo.title} - {todo.done ? '已完成' : '未完成'}
                </li>
              ))
            }
          </ul>
        ) : (<div>暂无待办事项</div>)
      }
      {isLoggedIn ? <div>已登录</div> : <div>未登录</div>}
      <button onClick={toggleLogin}>
        {isLoggedIn ? "退出登录" : "登录"}
      </button>
    </>
  )
}

export default App

// 组件拆分
// 组件复用
// 组件组合

重点知识点深度解析:

1. useState:让数据"活"起来
javascript 复制代码
const [name, setName] = useState('React');
  • useState 是 React 提供的 Hook(钩子),用于在函数组件中添加状态。
  • 它返回一个数组:[当前状态值, 更新函数]
  • 初始值是 'React'
  • 调用 setName('新名字') 会触发组件重新渲染,并更新 UI

神奇之处:你不需要手动操作 DOM!只要改状态,React 自动更新页面。

2. 状态可以是任何类型
  • name 是字符串
  • todos 是对象数组
  • isLoggedIn 是布尔值
3. JSX 中嵌入 JavaScript 表达式

{} 包裹任何 JS 表达式:

  • 变量:{name}
  • 三元运算:{isLoggedIn ? "退出" : "登录"}
  • 函数调用:{todos.map(...)}

注意:不能直接写 if 语句,但可以用三元运算或逻辑与 &&

4. className 替代 class

因为 class 是 JavaScript 的保留关键字,所以在 JSX 中必须写成:

javascript 复制代码
<span className="title">...</span>

对应的 CSS 在 App.css 中:

css 复制代码
.title {
  color: red;
}
5. 列表渲染与 key 属性
javascript 复制代码
todos.map((todo) => (
  <li key={todo.id}>...</li>
))
  • map 是数组方法,用于遍历生成 JSX 元素
  • 必须加 key!React 用它来识别哪些项发生了变化、添加或删除
  • 最佳实践:使用唯一 ID(如数据库主键),不要用数组索引!
6. 事件处理:onClick
html 复制代码
<button onClick={toggleLogin}>登录</button>
  • 事件名采用驼峰命名(onClick 而不是 onclick
  • 传入的是函数引用(不加括号!)
  • 函数内部调用 setisLoggedIn(!isLoggedIn) 切换状态
7. Fragment:<> </>

当不想多一层 <div> 时,用空标签包裹多个兄弟元素:

html 复制代码
<>
  <h1>标题</h1>
  <p>段落</p>
</>

编译后不会产生额外 DOM 节点。

8. 两种写 JSX 的方式
  • 语法糖(推荐)

    javascript 复制代码
    const element = <h2>内容</h2>
  • 原生 API

    javascript 复制代码
    const element2 = createElement('h2', null, '内容')

JSX 本质是 React.createElement() 的语法糖,但更直观易读。

9. 副作用示例:setTimeout
javascript 复制代码
setTimeout(() => {
  setName('React1');
}, 2000);

2 秒后自动把标题从 "React" 改成 "React1"。这展示了 状态驱动 UI 更新 的核心思想。

💡 注意:在真实项目中,这类副作用应使用 useEffect Hook 管理,但入门阶段可以先这样理解。


第七章:样式文件 index.cssApp.css

index.css(全局重置)

css 复制代码
* {
  margin: 0;
  padding: 0;
}

这是最简单的 CSS 重置,消除浏览器默认间距,让布局更可控。

App.css(组件样式)

css 复制代码
.title {
  color: red;
}

通过 import './App.css' 引入,作用于整个组件。未来你可以学习 CSS Modules 实现样式局部作用域。


第八章:总结所有核心知识点

根据以上所有代码,我们整理出 React 入门必知概念:

知识点 说明
JSX JavaScript 的语法扩展,允许在 JS 中写类似 HTML 的结构(XML in JS)
组件 = UI + 交互 + 状态 组件是封装了界面、逻辑和数据的独立单元
函数就是组件 只要函数返回 JSX,它就是一个 React 组件
组件化开发 将页面拆分为多个组件,像搭积木一样组合
组件树代替 DOM 树 React 内部维护虚拟 DOM 树,高效更新真实 DOM
响应式(Reactive) 数据变化自动触发 UI 更新
数据绑定(Data Binding) 通过状态(state)实现单向数据流
useState 用于在函数组件中声明和更新状态
key 属性 帮助 React 识别列表中每个元素的唯一性,提升性能
className JSX 中替代 HTML 的 class 属性
Fragment <> 用于包裹多个兄弟元素而不产生额外 DOM 节点
事件处理 使用 onClick 等驼峰命名事件,传入函数引用

第九章:动手实验建议

  1. 切换组件

    修改 main.jsx,注释掉 <App2 />,取消注释 <App />,观察静态页面效果。

  2. 添加新功能

    App.jsx 中:

    • 添加一个"添加待办"按钮
    • 实现点击"签到"按钮改变文字
  3. 调试技巧

    return 前加 console.log(name, todos),观察状态变化。

  4. 样式实验

    修改 App.css,给按钮加背景色:

    css 复制代码
    button {
      background: blue;
      color: white;
      border: none;
      padding: 8px 16px;
      cursor: pointer;
    }

第十章:结语 ------ 你已经迈出了第一步!

React 的学习曲线看似陡峭,但只要你理解了:

"组件是积木,状态是魔法,JSX 是桥梁"

你就已经掌握了现代前端开发的核心范式。

记住:

  • 不要怕犯错,React 的错误提示非常友好
  • 多动手,少死记
  • 组件化思维会让你受益终身

现在,关掉这篇文章,打开你的代码编辑器,亲手敲一遍这些代码。你会发现,React 并不可怕,反而充满乐趣!🚀

"编程不是关于写代码,而是关于解决问题。" ------ 而 React,给了你一套优雅的工具箱。

相关推荐
遇到困难睡大觉哈哈3 小时前
Harmony OS Web 组件:如何在新窗口中打开网页(实战分享)
前端·华为·harmonyos
Arciab3 小时前
C++ 学习_流程控制
c++·学习
HyperAI超神经3 小时前
【vLLM 学习】vLLM TPU 分析
开发语言·人工智能·python·学习·大语言模型·vllm·gpu编程
你脸上有BUG4 小时前
【工程化】前端打包时间优化
前端
TeleostNaCl4 小时前
Google Chrome 浏览器历史记录的存储位置
前端·chrome·经验分享
大模型教程4 小时前
前端可以转型AI工程师吗?那可太能了...
前端·llm·agent
赵财猫._.4 小时前
React Native鸿蒙开发实战(十):鸿蒙NEXT深度适配与未来展望
react native·react.js·harmonyos
转转技术团队4 小时前
前端开发应该了解的浏览器背后的黑科技
前端
2503_928411564 小时前
12.15 element-plus的一些组件(上)
前端·vue.js