React中Context的用法總結
更新時間:2025年01月10日 11:05:05 作者:傻小胖
Context?提供了一種在組件樹中共享數(shù)據(jù)的方式,而不必通過?props?顯式地逐層傳遞,主要用于共享那些對于組件樹中許多組件來說是"全局"的數(shù)據(jù),下面小編就來和大家簡單講講Context的用法吧
1. 基本概念
1.1 什么是 Context
Context 提供了一種在組件樹中共享數(shù)據(jù)的方式,而不必通過 props 顯式地逐層傳遞。它主要用于共享那些對于組件樹中許多組件來說是"全局"的數(shù)據(jù)。
1.2 基本用法
// 1. 創(chuàng)建 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 創(chuàng)建 Context
// 創(chuàng)建 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 動態(tài) 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);
// 創(chuàng)建自定義 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 創(chuàng)建自定義 Hook
// 創(chuàng)建自定義 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 性能優(yōu)化
// 使用 memo 避免不必要的重渲染
const UserInfo = React.memo(function UserInfo() {
const { name } = useUser();
return <div>User: {name}</div>;
});
???????// 分離狀態(tài),避免不相關的更新
function AppProvider({ children }) {
return (
<ThemeProvider>
<UserProvider>
<SettingsProvider>
{children}
</SettingsProvider>
</UserProvider>
</ThemeProvider>
);
}5. 常見問題和解決方案
5.1 避免重渲染
// 使用 useMemo 優(yōu)化 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
// 創(chuàng)建組合 Provider
function AppProviders({ children }) {
return (
<AuthProvider>
<ThemeProvider>
<UserProvider>
{children}
</UserProvider>
</ThemeProvider>
</AuthProvider>
);
}
???????// 使用組合 Provider
function App() {
return (
<AppProviders>
<MainApp />
</AppProviders>
);
}6. 總結
使用場景
- 主題切換
- 用戶認證狀態(tài)
- 語言偏好
- 全局配置
- 路由狀態(tài)共享
最佳實踐建議
- 適度使用 Context
- 創(chuàng)建專門的 Provider 組件
- 使用自定義 Hook 封裝 Context 邏輯
- 注意性能優(yōu)化
- 合理組織 Context 結構
到此這篇關于React中Context的用法總結的文章就介紹到這了,更多相關React Context內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vite+React搭建開發(fā)構建環(huán)境實踐記錄
這篇文章主要介紹了Vite+React搭建開發(fā)構建環(huán)境實踐,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09
React 遞歸手寫流程圖展示樹形數(shù)據(jù)的操作方法
這篇文章主要介紹了React 遞歸手寫流程圖展示樹形數(shù)據(jù)的操作方法,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11

