React 完整学习指南
# ⚛️ React 完整学习指南
适合人群:前端开发者、JavaScript开发者、移动端开发者
学习时间:3-6个月
前置知识:HTML、CSS、JavaScript基础、ES6+语法
React 是 Facebook 开发的用于构建用户界面的 JavaScript 库,是现代前端开发的核心技术之一。本指南将带你从零开始,系统性地学习 React 开发。
# 📚 你将学到什么
- React 基础 - 掌握组件、JSX、状态管理等核心概念
- Hooks 系统 - 学会使用现代 React 开发模式
- 状态管理 - 掌握 Redux、Zustand 等状态管理方案
- 性能优化 - 学会优化 React 应用性能
- 实战项目 - 完成完整的 React 应用开发
# 🎯 学习路径建议
graph TD
A[JavaScript基础] --> B[React基础]
B --> C[JSX语法]
C --> D[组件开发]
D --> E[Hooks系统]
E --> F[状态管理]
F --> G[路由管理]
G --> H[性能优化]
H --> I[实战项目]
# 📖 目录
# 🔧 前置知识
在开始学习 React 之前,你需要掌握以下基础知识:
# JavaScript 基础
- ES6+ 语法(箭头函数、解构赋值、模板字符串等)
- 数组方法(map、filter、reduce 等)
- 异步编程(Promise、async/await)
- 模块系统(import/export)
# 前端基础
- HTML5 语义化标签
- CSS3 布局(Flexbox、Grid)
- 响应式设计
- 浏览器开发者工具
# 推荐学习资源
- MDN JavaScript 指南 (opens new window) - JavaScript基础语法
- ES6 入门教程 (opens new window) - 现代JavaScript特性
- CSS 布局指南 (opens new window) - CSS布局基础
完整学习资源:请参考文档末尾的"学习资源"章节。
# 🚀 环境搭建
# 1. 安装 Node.js
# 检查 Node.js 版本
node --version
npm --version
# 推荐使用 Node.js 18+ 版本
1
2
3
4
5
2
3
4
5
# 2. 创建 React 项目
# 使用 Create React App
npx create-react-app my-react-app
cd my-react-app
npm start
# 使用 Vite(推荐,更快)
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
npm run dev
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 3. 开发工具配置
# VS Code 推荐插件
{
"recommendations": [
"ms-vscode.vscode-typescript-next",
"bradlc.vscode-tailwindcss",
"esbenp.prettier-vscode",
"ms-vscode.vscode-eslint",
"formulahendry.auto-rename-tag",
"christian-kohler.path-intellisense"
]
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 项目结构
my-react-app/
├── public/
│ ├── index.html
│ └── favicon.ico
├── src/
│ ├── components/ # 组件目录
│ ├── pages/ # 页面目录
│ ├── hooks/ # 自定义 Hooks
│ ├── utils/ # 工具函数
│ ├── styles/ # 样式文件
│ ├── App.js # 主应用组件
│ └── index.js # 应用入口
├── package.json
└── README.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# ⚛️ React 基础
# 1. JSX 语法
JSX 是 JavaScript 的语法扩展,让你可以在 JavaScript 中编写类似 HTML 的代码。
# 基本语法
// 基本 JSX
const element = <h1>Hello, React!</h1>;
// 表达式
const name = "React";
const element = <h1>Hello, {name}!</h1>;
// 属性
const element = <div className="container" id="main">Content</div>;
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 条件渲染
function Greeting({ isLoggedIn, username }) {
return (
<div>
{isLoggedIn ? (
<h1>Welcome back, {username}!</h1>
) : (
<h1>Please log in.</h1>
)}
</div>
);
}
// 使用 && 操作符
function Mailbox({ unreadMessages }) {
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 && (
<h2>You have {unreadMessages.length} unread messages.</h2>
)}
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 列表渲染
function TodoList({ todos }) {
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>
{todo.text}
</li>
))}
</ul>
);
}
// 复杂列表渲染
function ProductList({ products }) {
return (
<div className="product-grid">
{products.map(product => (
<div key={product.id} className="product-card">
<img src={product.image} alt={product.name} />
<h3>{product.name}</h3>
<p>${product.price}</p>
<button onClick={() => addToCart(product.id)}>
Add to Cart
</button>
</div>
))}
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 2. 组件基础
# 函数组件
// 简单函数组件
function Welcome({ name }) {
return <h1>Hello, {name}!</h1>;
}
// 带状态的函数组件(使用 Hooks)
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
函数组件的特点:
- 简洁性:语法简洁,易于理解和编写
- 性能优化:React 16.8+ 支持 Hooks,性能与类组件相当
- 现代开发:React 官方推荐使用函数组件
- 易于测试:纯函数特性,便于单元测试
- 代码复用:通过自定义 Hooks 实现逻辑复用
- TypeScript 友好:类型推断更准确,类型定义更简单
# 类组件
class Welcome extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
handleClick = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<h1>Hello, {this.props.name}!</h1>
<p>Count: {this.state.count}</p>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
类组件的特点:
- 生命周期:提供完整的生命周期方法(componentDidMount、componentDidUpdate 等)
- 状态管理:通过 this.state 和 this.setState 管理状态
- 错误边界:可以实现错误边界(Error Boundaries)
- 历史兼容:React 早期版本的主要组件形式
- 复杂逻辑:适合处理复杂的组件逻辑和状态管理
- 学习成本:需要理解 this 绑定、生命周期等概念
注意:虽然类组件仍然被支持,但 React 官方推荐使用函数组件 + Hooks 的开发模式。
# Props 传递
// 父组件
function App() {
const user = { name: "John", age: 30 };
return (
<div>
<UserCard user={user} />
<UserCard name="Jane" age={25} />
</div>
);
}
// 子组件
function UserCard({ user, name, age }) {
const displayName = user ? user.name : name;
const displayAge = user ? user.age : age;
return (
<div className="user-card">
<h2>{displayName}</h2>
<p>Age: {displayAge}</p>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3. 事件处理
function EventHandling() {
const [inputValue, setInputValue] = useState('');
const [items, setItems] = useState([]);
// 输入处理
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
// 表单提交
const handleSubmit = (e) => {
e.preventDefault();
if (inputValue.trim()) {
setItems([...items, inputValue]);
setInputValue('');
}
};
// 删除项目
const handleDelete = (index) => {
setItems(items.filter((_, i) => i !== index));
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
value={inputValue}
onChange={handleInputChange}
placeholder="Enter item"
/>
<button type="submit">Add Item</button>
</form>
<ul>
{items.map((item, index) => (
<li key={index}>
{item}
<button onClick={() => handleDelete(index)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 4. 基础项目实践
# 计数器组件
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
const reset = () => setCount(0);
return (
<div className="counter">
<h2>Counter: {count}</h2>
<div className="buttons">
<button onClick={decrement}>-</button>
<button onClick={reset}>Reset</button>
<button onClick={increment}>+</button>
</div>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 待办事项应用
import { useState } from 'react';
function TodoApp() {
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
const addTodo = () => {
if (inputValue.trim()) {
setTodos([...todos, {
id: Date.now(),
text: inputValue,
completed: false
}]);
setInputValue('');
}
};
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
return (
<div className="todo-app">
<h1>Todo App</h1>
<div className="add-todo">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
placeholder="Add a new todo"
/>
<button onClick={addTodo}>Add</button>
</div>
<ul className="todo-list">
{todos.map(todo => (
<li key={todo.id} className={todo.completed ? 'completed' : ''}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span>{todo.text}</span>
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 🎣 Hooks 系统
Hooks 是 React 16.8 引入的新特性,让你在函数组件中使用状态和其他 React 特性。
# 1. 基础 Hooks
# useState - 状态管理
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter name"
/>
<p>Hello, {name}!</p>
</div>
);
}
// 复杂状态管理
function UserProfile() {
const [user, setUser] = useState({
name: '',
email: '',
age: 0
});
const updateUser = (field, value) => {
setUser(prev => ({
...prev,
[field]: value
}));
};
return (
<div>
<input
value={user.name}
onChange={(e) => updateUser('name', e.target.value)}
placeholder="Name"
/>
<input
value={user.email}
onChange={(e) => updateUser('email', e.target.value)}
placeholder="Email"
/>
<input
type="number"
value={user.age}
onChange={(e) => updateUser('age', parseInt(e.target.value))}
placeholder="Age"
/>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# useEffect - 副作用处理
import { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
// 组件挂载时执行
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, []); // 空依赖数组,只在挂载时执行
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return <div>Data: {JSON.stringify(data)}</div>;
}
// 带依赖的 useEffect
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
// 当 userId 改变时重新获取数据
const fetchUser = async () => {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
setUser(userData);
};
if (userId) {
fetchUser();
}
}, [userId]); // 依赖 userId
return user ? <div>{user.name}</div> : <div>Loading...</div>;
}
// 清理副作用
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
// 清理函数
return () => clearInterval(interval);
}, []);
return <div>Timer: {seconds}s</div>;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# useContext - 上下文使用
import { createContext, useContext, useState } from 'react';
// 创建上下文
const ThemeContext = createContext();
// 提供者组件
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
// 使用上下文的组件
function ThemedButton() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button
onClick={toggleTheme}
style={{
backgroundColor: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#333' : '#fff'
}}
>
Toggle Theme
</button>
);
}
// 应用组件
function App() {
return (
<ThemeProvider>
<ThemedButton />
</ThemeProvider>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 2. 高级 Hooks
# useCallback - 函数缓存
减少可能的重新渲染。 skipping-re-rendering-of-components (opens new window)
import { useState, useCallback, memo } from 'react';
// 子组件
const ExpensiveChild = memo(({ onClick, data }) => {
console.log('ExpensiveChild rendered');
return (
<div>
<p>Data: {data}</p>
<button onClick={onClick}>Click me</button>
</div>
);
});
// 父组件
function Parent() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
// 使用 useCallback 缓存函数
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []); // 空依赖数组,函数不会重新创建
return (
<div>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter name"
/>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<ExpensiveChild onClick={handleClick} data={name} />
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# useMemo - 值缓存
import { useState, useMemo } from 'react';
function ExpensiveCalculation() {
const [count, setCount] = useState(0);
const [items, setItems] = useState([]);
// 使用 useMemo 缓存计算结果
const expensiveValue = useMemo(() => {
console.log('Calculating expensive value...');
return items.reduce((sum, item) => sum + item.value, 0);
}, [items]); // 只有当 items 改变时才重新计算
const addItem = () => {
setItems([...items, { value: Math.random() * 100 }]);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<p>Items: {items.length}</p>
<button onClick={addItem}>Add Item</button>
<p>Expensive Value: {expensiveValue}</p>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# useRef - 引用管理
import { useRef, useEffect } from 'react';
function RefExample() {
const inputRef = useRef(null);
const countRef = useRef(0);
useEffect(() => {
// 聚焦到输入框
inputRef.current?.focus();
}, []);
const handleClick = () => {
// 使用 ref 访问 DOM 元素
inputRef.current?.focus();
// 使用 ref 存储可变值
countRef.current += 1;
console.log('Click count:', countRef.current);
};
return (
<div>
<input ref={inputRef} placeholder="Focus me" />
<button onClick={handleClick}>Focus Input</button>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# useReducer - 复杂状态管理
import { useReducer } from 'react';
// 定义 reducer
function todoReducer(state, action) {
switch (action.type) {
case 'ADD_TODO':
return [...state, {
id: Date.now(),
text: action.text,
completed: false
}];
case 'TOGGLE_TODO':
return state.map(todo =>
todo.id === action.id
? { ...todo, completed: !todo.completed }
: todo
);
case 'DELETE_TODO':
return state.filter(todo => todo.id !== action.id);
default:
return state;
}
}
function TodoApp() {
const [todos, dispatch] = useReducer(todoReducer, []);
const [inputValue, setInputValue] = useState('');
const addTodo = () => {
if (inputValue.trim()) {
dispatch({ type: 'ADD_TODO', text: inputValue });
setInputValue('');
}
};
const toggleTodo = (id) => {
dispatch({ type: 'TOGGLE_TODO', id });
};
const deleteTodo = (id) => {
dispatch({ type: 'DELETE_TODO', id });
};
return (
<div>
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
/>
<button onClick={addTodo}>Add Todo</button>
<ul>
{todos.map(todo => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
{todo.text}
</span>
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 3. 自定义 Hooks
# 常用自定义 Hooks
// 自定义 Hook:数据获取
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// 使用自定义 Hook
function UserProfile({ userId }) {
const { data: user, loading, error } = useFetch(`/api/users/${userId}`);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return <div>{user?.name}</div>;
}
// 自定义 Hook:本地存储
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setValue = (value) => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue];
}
// 使用本地存储 Hook
function Settings() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
const [language, setLanguage] = useLocalStorage('language', 'en');
return (
<div>
<select value={theme} onChange={(e) => setTheme(e.target.value)}>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
<select value={language} onChange={(e) => setLanguage(e.target.value)}>
<option value="en">English</option>
<option value="zh">中文</option>
</select>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# 🔄 状态管理
# 1. Redux Toolkit
Redux Toolkit 是 Redux 的官方推荐工具集,简化了 Redux 的使用。
# 安装和配置
npm install @reduxjs/toolkit react-redux
1
# Store 配置
// store/index.js
import { configureStore } from '@reduxjs/toolkit';
import counterSlice from './slices/counterSlice';
import userSlice from './slices/userSlice';
export const store = configureStore({
reducer: {
counter: counterSlice,
user: userSlice,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# Slice 创建
// store/slices/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 异步操作
// store/slices/userSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
// 异步 thunk
export const fetchUser = createAsyncThunk(
'user/fetchUser',
async (userId) => {
const response = await fetch(`/api/users/${userId}`);
return response.json();
}
);
const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
loading: false,
error: null,
},
reducers: {
clearUser: (state) => {
state.user = null;
},
},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.loading = true;
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.loading = false;
state.user = action.payload;
})
.addCase(fetchUser.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message;
});
},
});
export const { clearUser } = userSlice.actions;
export default userSlice.reducer;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 在组件中使用
// components/Counter.jsx
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from '../store/slices/counterSlice';
function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
<button onClick={() => dispatch(incrementByAmount(5))}>+5</button>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2. Zustand
Zustand 是一个轻量级的状态管理库,API 简洁易用。
# 安装
npm install zustand
1
# 创建 Store
// store/useStore.js
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
export default useStore;
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 在组件中使用
// components/Counter.jsx
import useStore from '../store/useStore';
function Counter() {
const { count, increment, decrement, reset } = useStore();
return (
<div>
<span>{count}</span>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={reset}>Reset</button>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 3. Context + useReducer
使用 React 内置的状态管理方案。
// context/AppContext.js
import { createContext, useContext, useReducer } from 'react';
const AppContext = createContext();
// Reducer
function appReducer(state, action) {
switch (action.type) {
case 'SET_USER':
return { ...state, user: action.payload };
case 'SET_LOADING':
return { ...state, loading: action.payload };
case 'SET_ERROR':
return { ...state, error: action.payload };
default:
return state;
}
}
// Provider
export function AppProvider({ children }) {
const [state, dispatch] = useReducer(appReducer, {
user: null,
loading: false,
error: null,
});
return (
<AppContext.Provider value={{ state, dispatch }}>
{children}
</AppContext.Provider>
);
}
// Hook
export function useApp() {
const context = useContext(AppContext);
if (!context) {
throw new Error('useApp must be used within AppProvider');
}
return context;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# ⚡ 性能优化
# 1. React.memo
import { memo } from 'react';
// 使用 memo 包装组件
const ExpensiveComponent = memo(({ data, onClick }) => {
console.log('ExpensiveComponent rendered');
return (
<div>
<p>{data}</p>
<button onClick={onClick}>Click me</button>
</div>
);
});
// 自定义比较函数
const MyComponent = memo(({ user }) => {
return <div>{user.name}</div>;
}, (prevProps, nextProps) => {
return prevProps.user.id === nextProps.user.id;
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2. useMemo 和 useCallback
import { useState, useMemo, useCallback } from 'react';
function ExpensiveComponent({ items, filter }) {
// 缓存计算结果
const filteredItems = useMemo(() => {
console.log('Filtering items...');
return items.filter(item => item.category === filter);
}, [items, filter]);
// 缓存函数
const handleClick = useCallback((id) => {
console.log('Item clicked:', id);
}, []);
return (
<div>
{filteredItems.map(item => (
<div key={item.id} onClick={() => handleClick(item.id)}>
{item.name}
</div>
))}
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3. 代码分割和懒加载
import { lazy, Suspense } from 'react';
// 懒加载组件
const LazyComponent = lazy(() => import('./LazyComponent'));
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
// 路由级别的代码分割
import { lazy } from 'react';
import { Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 🚀 实战项目
# 电商购物车应用
// components/Cart.jsx
import { useState, useMemo } from 'react';
function Cart() {
const [items, setItems] = useState([
{ id: 1, name: 'Product 1', price: 10, quantity: 1 },
{ id: 2, name: 'Product 2', price: 20, quantity: 2 },
]);
const total = useMemo(() => {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}, [items]);
const updateQuantity = (id, quantity) => {
setItems(items.map(item =>
item.id === id ? { ...item, quantity } : item
));
};
const removeItem = (id) => {
setItems(items.filter(item => item.id !== id));
};
return (
<div className="cart">
<h2>Shopping Cart</h2>
{items.map(item => (
<div key={item.id} className="cart-item">
<span>{item.name}</span>
<span>${item.price}</span>
<input
type="number"
value={item.quantity}
onChange={(e) => updateQuantity(item.id, parseInt(e.target.value))}
min="1"
/>
<button onClick={() => removeItem(item.id)}>Remove</button>
</div>
))}
<div className="total">Total: ${total}</div>
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# ❓ 常见问题
# Q1: 什么时候使用 useCallback 和 useMemo?
A: 使用场景:
- useCallback: 当函数作为 props 传递给子组件时
- useMemo: 当有昂贵的计算需要缓存时
- 注意: 不要过度使用,只在真正需要时使用
# Q2: 如何避免不必要的重新渲染?
A: 优化策略:
- 使用
React.memo包装组件 - 使用
useCallback缓存函数 - 使用
useMemo缓存计算结果 - 避免在 render 中创建新对象
# Q3: 如何处理异步数据获取?
A: 推荐方案:
// 使用自定义 Hook
function useAsyncData(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Q4: 如何调试 React 应用?
A: 调试工具:
- React Developer Tools: 浏览器扩展
- console.log: 在组件中添加日志
- React.StrictMode: 开发模式下启用严格模式
- Error Boundaries: 捕获和处理错误
# Q5: 如何优化大型列表的性能?
A: 优化方案:
- 使用虚拟化列表(react-window, react-virtualized)
- 使用
React.memo优化列表项 - 实现分页或无限滚动
- 使用
key属性优化列表渲染
# 📚 学习资源
# 官方文档
- React 官方文档 (opens new window) - 最新的 React 官方文档
- React 中文文档 (opens new window) - 中文版官方文档
- React 参考 (opens new window) - API 参考文档
- React Native (opens new window) - 移动端开发
# 在线教程
- React 官方教程 (opens new window) - 官方交互式教程
- React 实战教程 (opens new window) - 深度实战教程
- React 模式 (opens new window) - React 设计模式
- React 最佳实践 (opens new window) - 官方最佳实践
# 工具和库
- Create React App (opens new window) - 官方脚手架工具
- Vite (opens new window) - 快速构建工具
- Redux Toolkit (opens new window) - 状态管理工具
- React Router (opens new window) - 路由管理
- React Query (opens new window) - 数据获取库
# 社区资源
- React 官方论坛 (opens new window) - 官方讨论社区
- Stack Overflow React 标签 (opens new window) - 技术问答
- Reddit r/reactjs (opens new window) - Reddit 社区
- React 中文社区 (opens new window) - 中文开发者社区
# 实践项目
- React 项目集合 (opens new window) - 个人项目集合
- React 示例代码 (opens new window) - 代码示例
- React 最佳实践 (opens new window) - 最佳实践代码
# 🎯 学习建议
# 时间安排
- 每日学习时间: 2-4小时
- 每周项目实践: 至少一个完整项目
- 定期复习: 每周末回顾本周学习内容
# 学习方法
- 理论结合实践: 每学一个概念就动手实现
- 项目驱动: 通过完整项目巩固知识点
- 社区参与: 参与开源项目和技术讨论
- 持续学习: 关注React生态发展,保持技术更新
# 技能评估
- 基础阶段: 能够独立开发简单组件
- 进阶阶段: 掌握 Hooks 和组件通信
- 高级阶段: 熟练使用状态管理和性能优化
- 实战阶段: 能够独立完成复杂项目
# 🎉 总结
通过本指南的学习,你已经掌握了:
- React 基础 - 理解了组件、JSX、状态管理等核心概念
- Hooks 系统 - 学会了使用现代 React 开发模式
- 状态管理 - 掌握了 Redux、Zustand 等状态管理方案
- 性能优化 - 学会了优化 React 应用性能
- 实战项目 - 完成了完整的 React 应用开发
# 下一步学习建议
- 深入学习 TypeScript - 提升代码质量和开发效率
- 学习测试 - 掌握 Jest 和 React Testing Library
- 探索 React 生态 - 学习 Next.js、Gatsby 等框架
- 参与开源项目 - 提升实际开发经验
# 记住这些要点
- 实践是最好的老师 - 多写代码、多调试、多思考
- 理解原理 - 不要只停留在使用层面,要理解背后的原理
- 社区参与 - 积极参与社区讨论,分享经验
React 是现代前端开发的核心技术之一,掌握它将为你的职业发展带来巨大帮助。继续深入学习,探索更多可能性!🚀
上次更新: 2025/10/09, 22:57:36