第三章:React 进阶
Context API 和状态管理
1. 为什么需要状态管理?
在复杂的 React 应用中,组件之间的状态共享和传递可能变得非常繁琐。通过 props 层层传递数据("prop drilling")会导致代码难以维护。状态管理工具(如 Context API 或 Redux)可以解决这个问题,提供集中式的状态管理方案。
2. Context API 简介
Context API 是 React 内置的状态管理机制,允许数据在组件树中跨层级传递,而无需手动逐层传递 props。
核心概念:
React.createContext: 创建一个 Context 对象Context.Provider: 提供数据的组件Context.Consumer或useContextHook: 消费数据的组件
3. 使用 Context API 的步骤
(1) 创建 Context
import { createContext } from 'react';
const ThemeContext = createContext('light'); // 默认值
(2) 提供 Context
function App() {
const [theme, setTheme] = useState('dark');
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
</ThemeContext.Provider>
);
}
(3) 消费 Context
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={theme}>按钮</button>;
}
4. 结合 useReducer 实现复杂状态管理
对于更复杂的状态逻辑,可以结合 useReducer 使用:
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function CounterProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<CounterContext.Provider value={{ state, dispatch }}>
{children}
</CounterContext.Provider>
);
}
5. 何时选择 Redux?
虽然 Context API 适合大多数场景,但在以下情况可能需要 Redux:
- 应用状态非常复杂
- 需要时间旅行调试功能
- 需要中间件处理异步逻辑
- 需要更严格的状态更新模式
6. 性能优化提示
- 避免在高频更新的场景中使用 Context
- 将 Context 拆分为多个小 Context
- 使用 memo 或 useMemo 防止不必要的重新渲染
7. 实践建议
- 从组件本地状态开始,只在必要时提升状态
- 先尝试 Context API,再考虑 Redux
- 保持状态最小化,只存储必要数据
- 为 Context 提供清晰的类型定义(TypeScript)
示例项目
实现一个主题切换功能:
- 创建 ThemeContext
- 在根组件提供当前主题值
- 在深层子组件中消费主题值
- 添加切换主题的功能
// 完整示例
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 ThemedComponent() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<div className={`app ${theme}`}>
<button onClick={toggleTheme}>切换主题</button>
</div>
);
}
通过本章学习,你应该能够理解如何在 React 应用中有效管理状态,并根据项目需求选择合适的解决方案。
