Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як типізувати Context, щоб не перевіряти на null у кожному компоненті?

createContext потребує значення за замовчуванням. Для контексту з реальними даними (поточний користувач, кошик) осмисленого значення за замовчуванням немає, тому часто пишуть null:

type AuthContextValue = {
  user: User;
  logout: () => void;
};

const AuthContext = createContext<AuthContextValue | null>(null);

Тепер кожен useContext(AuthContext) повертає AuthContextValue | null, і в кожному компоненті потрібна перевірка. Набридливо - і перевірка однаково нічого не робить, бо провайдер завжди є.

Рішення - власний хук з перевіркою в одному місці:

export function useAuth(): AuthContextValue {
  const context = useContext(AuthContext);
  if (context === null) {
    throw new Error('useAuth треба викликати всередині <AuthProvider>');
  }
  return context;
}
function Header() {
  const { user, logout } = useAuth();   // AuthContextValue без null
  return <button onClick={logout}>Вийти, {user.name}</button>;
}

Переваги:

  • тип без null у компонентах;
  • зрозуміла помилка одразу, якщо компонент випадково відрендерили поза провайдером (замість Cannot read properties of null десь далі);
  • контекст можна не експортувати - лише хук і провайдер. Так менше способів використати його неправильно.

Провайдер разом із логікою:

export function AuthProvider({ user, children }: { user: User; children: ReactNode }) {
  const logout = useCallback(() => router.post('/logout'), []);
  const value = useMemo(() => ({ user, logout }), [user, logout]);
  return <AuthContext value={value}>{children}</AuthContext>;
}

У React 19 контекст можна рендерити напряму як провайдер - <AuthContext value={...}> замість <AuthContext.Provider value={...}>.

Альтернатива, коли розумне значення за замовчуванням є (тема, мова): createContext<Theme>('light') - перевірки на null не потрібні взагалі.

Пастка: createContext<AuthContextValue>(null!) чи {} as AuthContextValue - «заглушка» для компілятора. TypeScript замовкне, але компонент поза провайдером отримає null чи порожній об'єкт і впаде з незрозумілою помилкою під час виконання.

Докладніше в документації: TypeScript у React: useContext

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання