⚛️ React 技术学习指南

从入门到核心概念的全面掌握

📖 引言:认识 React

React 是由 Facebook 开发的用于构建用户界面的 JavaScript 库。它通过组件化声明式编程的设计思想,彻底改变了前端开发的方式。

React 解决的核心问题:

核心设计思想:

🧩 组件与 JSX

React 组件是构建应用的基本单元。JSX 是 JavaScript 的语法扩展,允许在 JS 中编写类似 HTML 的代码。

函数组件示例

function WelcomeMessage({ name }) { return <h1>欢迎, {name}!</h1>; } // 使用组件 <WelcomeMessage name="开发者" />

组件工作原理

Props name: "开发者" age: 25 Component 处理逻辑 JSX/DOM <h1>欢迎, 开发者!</h1> State (内部状态) count: 0

🔄 状态与生命周期

State (状态) 是组件内部的数据,当状态改变时,组件会重新渲染。useState 是最常用的 Hook。

计数器示例

function Counter() { const [count, setCount] = useState(0); return ( <div> <p>当前计数: {count}</p> <button onClick={() => setCount(count + 1)}> 增加 </button> </div> ); }

状态更新流程

用户交互 点击按钮 触发 状态更新 setCount(n+1) 触发 组件重渲染 Re-render 更新完成 UI 更新 显示新的 count 值

📡 Props 与数据流

React 采用单向数据流:数据从父组件通过 Props 传递给子组件,保证数据流向清晰可控。

父子组件通信示例

// 父组件 function UserList() { const users = [ { id: 1, name: '张三' }, { id: 2, name: '李四' } ]; return users.map(user => <UserItem key={user.id} user={user} /> ); } // 子组件 function UserItem({ user }) { return <div>{user.name}</div>; }

数据流向图

父组件 UserList users = [{...}, {...}] props ↓ props ↓ 子组件 UserItem user.id: 1 user.name: "张三" 子组件 UserItem user.id: 2 user.name: "李四" ✓ 单向数据流:父 → 子

🪝 Hooks 深入理解

Hooks 让函数组件拥有状态和生命周期能力。useEffect 用于处理副作用(如数据获取、订阅等)。

useEffect 示例

function UserProfile({ userId }) { const [user, setUser] = useState(null); useEffect(() => { // 组件挂载时获取数据 fetch(`/api/users/${userId}`) .then(res => res.json()) .then(data => setUser(data)); // 清理函数(组件卸载时执行) return () => { console.log('清理资源'); }; }, [userId]); // 依赖项:userId变化时重新执行 return <div>{user?.name}</div>; }

useEffect 执行流程

组件渲染 首次/重新渲染 检查依赖项 [userId] 是否发生变化? 执行清理函数 return () => {...} (如果存在) 跳过执行 不执行副作用 执行副作用函数

🌳 虚拟 DOM 与协调

React 通过虚拟 DOM (Virtual DOM) 优化性能。当状态改变时,React 先在内存中对比新旧虚拟 DOM 树,计算出最小差异,然后只更新必要的真实 DOM 节点。

虚拟 DOM 对比过程

旧虚拟 DOM <div id="app"> <h1>旧</h1> <p>内容</p> 新虚拟 DOM <div id="app"> <h1>新</h1> <p>内容</p> Diff 算法对比 ⚡ 差异计算结果 ✗ <h1> 文本变化: "旧" → "新" ✓ <p> 无变化,复用 只更新 <h1> 的文本节点

协调过程的关键优化:

✨ 最佳实践

1. 正确使用 key 属性

在渲染列表时,为每个元素提供唯一且稳定的 key,帮助 React 识别哪些元素发生了变化。

// ✓ 正确:使用唯一ID {users.map(user => <UserItem key={user.id} user={user} /> )} // ✗ 错误:使用索引(数据顺序变化时会出问题) {users.map((user, index) => <UserItem key={index} user={user} /> )}

2. 组件单一职责原则

每个组件应该只负责一个功能,保持组件小而专注,便于复用和测试。

// ✓ 好的设计:职责分离 function UserProfile({ user }) { return ( <> <UserAvatar url={user.avatar} /> <UserInfo name={user.name} email={user.email} /> </> ); }

3. 避免不必要的渲染

使用 React.memouseMemouseCallback 优化性能,但不要过度优化。

// 使用 React.memo 避免不必要的重渲染 const ExpensiveComponent = React.memo(({ data }) => { return <div>{/* 复杂渲染逻辑 */}</div>; }); // 使用 useMemo 缓存计算结果 const sortedData = useMemo(() => { return data.sort((a, b) => a.value - b.value); }, [data]);