1. 基本概念
1.1 什么是 Context
Context 提供了一种在组件树中共享数据的方式,而不必通过 props 显式地逐层传递。它主要用于共享那些对于组件树中许多组件来说是”全局”的数据。
1.2 基本用法
// 1. 创建 Context const ThemeContext = React.createContext('light'); // 2. 提供 Context function App() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } // 3. 消费 Context function Toolbar() { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { const theme = React.useContext(ThemeContext); return <button className={theme}>Themed Button</button>; }
2. Context API 详解
2.1 创建 Context
// 创建 Context 并设置默认值 const UserContext = React.createContext({ name: 'Guest', isAdmin: false }); // 导出 Context 供其他组件使用 export default UserContext;
2.2 Provider 组件
function App() { const [user, setUser] = useState({ name: 'John', isAdmin: true }); return ( <UserContext.Provider value={user}> <div className="app"> <MainContent /> <Sidebar /> </div> </UserContext.Provider> ); }
2.3 消费 Context
使用 useContext Hook(推荐)
function UserProfile() { const user = React.useContext(UserContext); return ( <div> <h2>User Profile</h2> <p>Name: {user.name}</p> <p>Role: {user.isAdmin ? 'Admin' : 'User'}</p> </div> ); }
使用 Consumer 组件
function UserRole() { return ( <UserContext.Consumer> {user => ( <span> Role: {user.isAdmin ? 'Admin' : 'User'} </span> )} </UserContext.Consumer> ); }
3. 高级用法
3.1 多个 Context 组合
const ThemeContext = React.createContext('light'); const UserContext = React.createContext({ name: 'Guest' }); function App() { return ( <ThemeContext.Provider value="dark"> <UserContext.Provider value={{ name: 'John' }}> <Layout /> </UserContext.Provider> </ThemeContext.Provider> ); } function Layout() { const theme = React.useContext(ThemeContext); const user = React.useContext(UserContext); return ( <div className={theme}> <header>Welcome, {user.name}</header> <main>Content</main> </div> ); }
3.2 动态 Context
const ThemeContext = React.createContext({ theme: 'light', toggleTheme: () => {} }); function ThemeProvider({ children }) { const [theme, setTheme] = useState('light'); const toggleTheme = () => { setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light'); }; return ( <ThemeContext.Provider value={{ theme, toggleTheme }}> {children} </ThemeContext.Provider> ); } function ThemeToggleButton() { const { theme, toggleTheme } = React.useContext(ThemeContext); return ( <button onClick={toggleTheme}> Current theme: {theme} </button> ); }
3.3 Context 与 TypeScript
// 定义 Context 类型 interface UserContextType { name: string; isAdmin: boolean; updateUser: (name: string) => void; } const UserContext = React.createContext<UserContextType | undefined>(undefined); // 创建自定义 Hook function useUser() { const context = React.useContext(UserContext); if (context === undefined) { throw new Error('useUser must be used within a UserProvider'); } return context; } // Provider 组件 function UserProvider({ children }: { children: React.ReactNode }) { const [name, setName] = useState('Guest'); const [isAdmin] = useState(false); const updateUser = (newName: string) => { setName(newName); }; return ( <UserContext.Provider value={{ name, isAdmin, updateUser }}> {children} </UserContext.Provider> ); }
4. 最佳实践
4.1 创建自定义 Hook
// 创建自定义 Hook 封装 Context 逻辑 function useTheme() { const context = React.useContext(ThemeContext); if (context === undefined) { throw new Error('useTheme must be used within a ThemeProvider'); } return context; } // 使用自定义 Hook function ThemedButton() { const { theme, toggleTheme } = useTheme(); return ( <button onClick={toggleTheme} className={theme}> Toggle Theme </button> ); }
4.2 分离 Context 逻辑
// contexts/theme.js export const ThemeContext = React.createContext({ theme: 'light', toggleTheme: () => {} }); export function ThemeProvider({ children }) { const [theme, setTheme] = useState('light'); const value = { theme, toggleTheme: () => setTheme(t => t === 'light' ? 'dark' : 'light') }; return ( <ThemeContext.Provider value={value}> {children} </ThemeContext.Provider> ); } export function useTheme() { const context = React.useContext(ThemeContext); if (context === undefined) { throw new Error('useTheme must be used within a ThemeProvider'); } return context; }
4.3 性能优化
// 使用 memo 避免不必要的重渲染 const UserInfo = React.memo(function UserInfo() { const { name } = useUser(); return <div>User: {name}</div>; }); // 分离状态,避免不相关的更新 function AppProvider({ children }) { return ( <ThemeProvider> <UserProvider> <SettingsProvider> {children} </SettingsProvider> </UserProvider> </ThemeProvider> ); }
5. 常见问题和解决方案
5.1 避免重渲染
// 使用 useMemo 优化 Context value function ThemeProvider({ children }) { const [theme, setTheme] = useState('light'); const value = useMemo(() => ({ theme, toggleTheme: () => setTheme(t => t === 'light' ? 'dark' : 'light') }), [theme]); return ( <ThemeContext.Provider value={value}> {children} </ThemeContext.Provider> ); }
5.2 处理嵌套 Context
// 创建组合 Provider function AppProviders({ children }) { return ( <AuthProvider> <ThemeProvider> <UserProvider> {children} </UserProvider> </ThemeProvider> </AuthProvider> ); } // 使用组合 Provider function App() { return ( <AppProviders> <MainApp /> </AppProviders> ); }
6. 总结
使用场景
- 主题切换
- 用户认证状态
- 语言偏好
- 全局配置
- 路由状态共享
最佳实践建议
- 适度使用 Context
- 创建专门的 Provider 组件
- 使用自定义 Hook 封装 Context 逻辑
- 注意性能优化
- 合理组织 Context 结构
到此这篇关于React中Context的用法总结的文章就介绍到这了,更多相关React Context内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源链接:https://www.jb51.net/javascript/334030xkc.htm
© 版权声明
本站所有资源来自于网络,仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您(转载者)自己承担!
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
THE END
暂无评论内容