React 完全入门指南:从基础概念到组件协作

文章目录

    • [1. React 概览](#1. React 概览)
    • [2. 创建和嵌套组件](#2. 创建和嵌套组件)
    • [3. 使用 JSX 编写标签](#3. 使用 JSX 编写标签)
    • [4. 添加样式](#4. 添加样式)
      • [4.1 内联样式(style 属性)](#4.1 内联样式(style 属性))
      • [4.2 CSS 类名(推荐)](#4.2 CSS 类名(推荐))
      • [4.3 CSS Modules(避免命名冲突)](#4.3 CSS Modules(避免命名冲突))
    • [5. 显示数据](#5. 显示数据)
    • [6. 条件渲染](#6. 条件渲染)
      • [6.1 `if` 语句(在组件函数内部)](#6.1 if 语句(在组件函数内部))
      • [6.2 三元运算符](#6.2 三元运算符)
      • [6.3 逻辑与 (&&) 运算符](#6.3 逻辑与 (&&) 运算符)
    • [7. 渲染列表](#7. 渲染列表)
    • [8. 响应事件](#8. 响应事件)
    • [9. 更新界面:State 与 useState](#9. 更新界面:State 与 useState)
    • [10. 使用 Hook](#10. 使用 Hook)
      • [10.1 `useState` ------ 管理状态](#10.1 useState —— 管理状态)
      • [10.2 `useEffect` ------ 处理副作用(数据请求、订阅、DOM 操作等)](#10.2 useEffect —— 处理副作用(数据请求、订阅、DOM 操作等))
      • [10.3 自定义 Hook](#10.3 自定义 Hook)
    • [11. 组件间共享数据](#11. 组件间共享数据)
      • [11.1 通过 Props 传递数据](#11.1 通过 Props 传递数据)
      • [11.2 共享数据:子组件 → 父组件(回调函数)](#11.2 共享数据:子组件 → 父组件(回调函数))
      • [11.3 深层传递:Context API](#11.3 深层传递:Context API)
      • [11.4 全局状态管理(进阶)](#11.4 全局状态管理(进阶))
    • 总结

1. React 概览

React 是由 Facebook 开发并开源的一个用于构建用户界面的 JavaScript 库。它的核心思想是组件化------将 UI 拆分成独立、可复用的部分,每个部分只关心自己的逻辑和渲染。

  • 声明式编程:你只需要描述 UI 在不同状态下的样子,React 会自动高效地更新和渲染。
  • 组件化:基于组件的开发模式,提高代码复用率和可维护性。
  • 虚拟 DOM:通过内存中的虚拟 DOM 树和高效的 diff 算法,减少直接操作真实 DOM 的次数,提升性能。
  • 生态丰富:React Router、Redux、Next.js 等成熟解决方案覆盖各种开发场景。

2. 创建和嵌套组件

React 组件有两种常见形式:函数组件 (现在的主流)和 类组件(旧项目居多)。函数组件简单直观,配合 Hook 可以拥有完整能力。

jsx 复制代码
// 定义一个函数组件
function Welcome() {
  return <h1>Hello, React!</h1>;
}

// 定义另一个组件,并嵌套使用 Welcome 组件
function App() {
  return (
    <div>
      <Welcome />
      <Welcome />
    </div>
  );
}

export default App;
  • 组件名必须大写字母开头,否则 React 会将其当作普通 HTML 标签。
  • 一个组件可以返回多个元素,但必须被一个父元素包裹,或者使用 <></> (Fragment)。

3. 使用 JSX 编写标签

JSX 是 JavaScript 的语法扩展,允许你在 JavaScript 文件中直接编写类似 HTML 的标记。

jsx 复制代码
const element = <h1 className="greeting">Hello, world!</h1>;

关键点:

  • 使用 className 而不是 class
  • 嵌入 JavaScript 表达式用 {} 包裹。
  • 标签必须正确闭合(如 <img />)。
jsx 复制代码
const name = "Alice";
const element = <p>Hello, {name}!</p>;

4. 添加样式

React 中有多种方式为组件添加样式:

4.1 内联样式(style 属性)

jsx 复制代码
<div style={{ color: 'red', fontSize: '20px' }}>Styled Text</div>

4.2 CSS 类名(推荐)

jsx 复制代码
// App.css
.title {
  color: blue;
}

// App.jsx
import './App.css';

function App() {
  return <h1 className="title">Hello World</h1>;
}

4.3 CSS Modules(避免命名冲突)

jsx 复制代码
// Button.module.css
.btn { background: green; }

// Button.jsx
import styles from './Button.module.css';

function Button() {
  return <button className={styles.btn}>Click</button>;
}

5. 显示数据

在 JSX 中使用 {} 可以显示任何 JavaScript 值(字符串、数字、数组、对象属性等)。

jsx 复制代码
const user = { name: 'John', age: 25 };

function Profile() {
  return (
    <div>
      <p>Name: {user.name}</p>
      <p>Age: {user.age}</p>
    </div>
  );
}
  • 不能直接渲染对象作为文本内容,但可以渲染对象的属性或转换成字符串。
  • 可以渲染数组,React 会自动将其元素拼接展示。

6. 条件渲染

根据需要显示不同的 UI 内容。

6.1 if 语句(在组件函数内部)

jsx 复制代码
function Greeting({ isLoggedIn }) {
  if (isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign in.</h1>;
}

6.2 三元运算符

jsx 复制代码
function Greeting({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign in.</h1>}
    </div>
  );
}

6.3 逻辑与 (&&) 运算符

jsx 复制代码
function Notification({ count }) {
  return (
    <div>
      {count > 0 && <p>You have {count} new messages.</p>}
    </div>
  );
}

7. 渲染列表

使用 JavaScript 的 map() 方法将数组转换为 JSX 元素数组。

jsx 复制代码
const products = ['Apple', 'Banana', 'Orange'];

function ShoppingList() {
  return (
    <ul>
      {products.map(product => (
        <li key={product}>{product}</li>
      ))}
    </ul>
  );
}
  • 必须提供 key 属性:帮助 React 识别哪些元素改变了、添加了或删除了。通常使用数据中的唯一 ID,避免使用索引(除非列表是静态的且不会重新排序)。

8. 响应事件

在 JSX 中通过 onClickonChange 等驼峰命名属性绑定事件处理函数。

jsx 复制代码
function Button() {
  function handleClick() {
    alert('Button clicked!');
  }

  return <button onClick={handleClick}>Click me</button>;
}
  • 事件处理函数通常是组件内部定义的函数。
  • 如果需要传递参数,可以使用箭头函数包装:onClick={() => handleDelete(id)}

9. 更新界面:State 与 useState

React 组件中的"记忆"功能------state。当 state 改变时,组件会重新渲染,界面自动更新。

使用 useState Hook 在函数组件中添加 state:

jsx 复制代码
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);  // 初始值 0

  function increment() {
    setCount(count + 1);  // 更新 state
  }

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>+1</button>
    </div>
  );
}
  • useState 返回一个数组:当前 state 值 和 更新它的函数。
  • 调用更新函数会触发组件重新渲染。
  • 重要:state 更新可能是异步的,且不要直接修改 state 对象。

10. 使用 Hook

Hook 是 React 16.8 引入的特性,让你在函数组件中使用 state 和其他 React 特性。常见内置 Hook:

10.1 useState ------ 管理状态

上面已介绍。

10.2 useEffect ------ 处理副作用(数据请求、订阅、DOM 操作等)

jsx 复制代码
import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // 组件挂载后或 userId 变化时执行
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => setUser(data));
  }, [userId]);  // 依赖数组:只有当 userId 改变时才重新执行

  if (!user) return <div>Loading...</div>;
  return <div>{user.name}</div>;
}
  • 可以返回一个清理函数,用于取消订阅、清除定时器等。

10.3 自定义 Hook

将组件逻辑提取到可复用的函数中。

jsx 复制代码
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}

11. 组件间共享数据

在 React 中,数据通常从上到下 (父组件向子组件)通过 props 传递。

11.1 通过 Props 传递数据

jsx 复制代码
function Child({ message }) {
  return <p>{message}</p>;
}

function Parent() {
  return <Child message="Hello from Parent!" />;
}
  • Props 是只读的,子组件不能修改接收到的 props。

11.2 共享数据:子组件 → 父组件(回调函数)

父组件将一个函数作为 props 传给子组件,子组件调用该函数并传递数据。

jsx 复制代码
function Child({ onData }) {
  return <button onClick={() => onData('Child data')}>Send Data</button>;
}

function Parent() {
  function handleData(data) {
    console.log(data);  // 'Child data'
  }
  return <Child onData={handleData} />;
}

11.3 深层传递:Context API

当很多层级的组件都需要访问同一份数据时(如主题、用户信息),可以使用 Context 避免 props 逐层传递(props drilling)。

jsx 复制代码
// 创建 Context
const ThemeContext = React.createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Button</button>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}
  • Provider 提供数据,useContext 在任意后代组件中消费数据。

11.4 全局状态管理(进阶)

对于大型应用,可以引入 ReduxZustandJotai 等状态管理库。但很多场景下 React 自带的 Context + useReducer 已经足够。


总结

概念 核心要点
组件 函数或类,返回 JSX,大写字母开头。
JSX 在 JS 中写 HTML 标签,使用 {} 嵌入表达式,className 代替 class
样式 内联样式、普通 CSS、CSS Modules。
数据渲染 {} 显示变量,不能直接渲染对象。
条件渲染 if 语句、三元运算符、逻辑与 (&&)。
列表 map() 方法,必须带 key 属性。
事件 驼峰命名事件名,传递函数引用。
State useState 定义,更新触发重绘。
副作用 useEffect 处理数据请求、订阅等。
组件通信 props 父→子,回调函数 子→父,Context 跨层传递。

React 的组件化思想和数据流模型让构建大型前端应用变得清晰可控。掌握了这些基础概念,你就可以开始动手开发真实的 React 应用了。不断练习、查阅官方文档,并尝试使用 React 生态中的工具(如 React DevTools)来调试和优化你的应用,你很快就会成为一名合格的 React 开发者。

相关推荐
前端摸鱼匠2 小时前
Vue 3 的defineEmits编译器宏:详解<script setup>中defineEmits的使用
前端·javascript·vue.js·前端框架·ecmascript
里欧跑得慢2 小时前
Flutter 测试全攻略:从单元测试到集成测试的完整实践
前端·css·flutter·web
Jagger_2 小时前
前端整洁架构详解
前端
徐小夕3 小时前
我花一天时间Vibe Coding的开源AI工具,一键检测你的电脑能跑哪些AI大模型
前端·javascript·github
英俊潇洒美少年3 小时前
Vue3 企业级封装:useEventListener + 终极版 BaseEcharts 组件
前端·javascript·vue.js
嵌入式×边缘AI:打怪升级日志3 小时前
使用JsonRPC实现前后台
前端·后端
小码哥_常4 小时前
深度剖析:为什么Android选择了Binder
前端
方安乐5 小时前
单元测试之helper函数
前端·javascript·单元测试
音仔小瓜皮5 小时前
【Web八股】深入理解浏览器DOM事件流,灵活控制它!
前端·web