Будет ли работать Capturing при наличии события onClick на родительском и дочернем элементах?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
React Context: цели и применение
React Context — встроенный механизм для управления глобальным состоянием приложения, позволяющий избежать передачи данных через все уровни компонентов (problem props drilling). Вот основные цели его использования:
1. Предотвращение Props Drilling
Context решает проблему, когда нужно передать данные на несколько уровней вниз через промежуточные компоненты:
// БЕЗ Context — nightmare
function App() {
const user = { name: "Alice", theme: "dark" };
return <Level1 user={user} theme={theme} />;
}
function Level1({ user, theme }) {
return <Level2 user={user} theme={theme} />;
}
function Level2({ user, theme }) {
return <Level3 user={user} theme={theme} />;
}
function Level3({ user, theme }) {
return <div>{user.name} - {theme}</div>;
}
// С Context — чисто
const UserContext = React.createContext();
const ThemeContext = React.createContext();
function App() {
return (
<UserContext.Provider value={{ name: "Alice" }}>
<ThemeContext.Provider value="dark">
<Level1 />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
function Level3() {
const user = useContext(UserContext);
const theme = useContext(ThemeContext);
return <div>{user.name} - {theme}</div>;
}
2. Управление глобальным состоянием приложения
Context идеален для данных, нужных всему приложению:
- Аутентификация — текущий пользователь, токены, права доступа
- Тема (light/dark mode)
- Язык (i18n)
- Уведомления (глобальная система модалей/тостов)
- Настройки пользователя
const AuthContext = React.createContext();
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("/api/me")
.then(res => res.json())
.then(data => {
setUser(data);
setLoading(false);
});
}, []);
return (
<AuthContext.Provider value={{ user, loading }}>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
return useContext(AuthContext);
}
3. Избежание необоснованной сложности
Для простых приложений Context лучше, чем Redux/Zustand:
- Нет внешних зависимостей
- Меньше boilerplate кода
- Встроен в React
const NotificationContext = React.createContext();
function notificationReducer(state, action) {
switch (action.type) {
case "ADD":
return [...state, action.payload];
case "REMOVE":
return state.filter(n => n.id !== action.payload);
default:
return state;
}
}
export function NotificationProvider({ children }) {
const [notifications, dispatch] = useReducer(
notificationReducer,
[]
);
return (
<NotificationContext.Provider value={{ notifications, dispatch }}>
{children}
</NotificationContext.Provider>
);
}
4. Управление состоянием UI (не бизнес-логики)
Важное уточнение: Context хорошо работает для:
- UI состояния: открыта ли модаль, активная вкладка, видна ли боковая панель
- Глобальных данных: пользователь, тема
НО не для:
- Часто обновляемого состояния (будут лишние ре-рендеры)
- Сложной бизнес-логики (для этого Redux/Zustand/Jotai)
5. Когда НЕ использовать Context
- Состояние обновляется часто (> 10 раз в секунду) — Context вызовет лишние ре-рендеры
- Сложная логика с множеством action'ов — лучше Redux
- Нужно devtools для отладки — Redux имеет лучшие инструменты
- Асинхронные операции — Context не очень удобен, лучше use-query/SWR
Практический пример
В промышленных приложениях Context часто используется вместе с useReducer для более сложной логики:
const AppContext = React.createContext();
function appReducer(state, action) {
switch (action.type) {
case "SET_USER":
return { ...state, user: action.payload };
case "TOGGLE_THEME":
return { ...state, theme: state.theme === "light" ? "dark" : "light" };
default:
return state;
}
}
export function AppProvider({ children }) {
const [state, dispatch] = useReducer(appReducer, {
user: null,
theme: "light"
});
return (
<AppContext.Provider value={{ state, dispatch }}>
{children}
</AppContext.Provider>
);
}
Итог
React Context используется для управления глобальным состоянием, предотвращения props drilling и синхронизации данных между компонентами. Это встроенное решение, которое идеально подходит для аутентификации, темы, языка и уведомлений. Для более сложных случаев (частые обновления, большой объем логики) лучше использовать специализированные библиотеки вроде Redux или Zustand.