useContext는 전역 상태 공유에 사용되는 훅이야. Redux 없이도 간단한 상태를 여러 컴포넌트에서 공유할 수 있어.

TypeScript와 함께 사용할 때는 Context의 타입 정의가 핵심이야.


📘 예제 41: Context 객체 생성과 타입

import { createContext } from 'react';

type Theme = 'light' | 'dark';

const ThemeContext = createContext<Theme>('light');

✅ createContext<Type>(defaultValue) 형식으로 타입을 지정해줘야 useContext 사용할 때 타입 추론이 정확해져.


📘 예제 42: Provider로 값 주입

import { useState } from 'react';

const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
  const [theme, setTheme] = useState<'light' | 'dark'>('light');

  return (
    <ThemeContext.Provider value={theme}>
      {children}
    </ThemeContext.Provider>
  );
};

✅ Context는 Provider 컴포넌트로 감싸야 실제 값이 자식 컴포넌트에 전달돼. 기본값만으로는 상태가 바뀌지 않아.


📘 예제 43: useContext 훅으로 사용

import { useContext } from 'react';

const Header = () => {
  const theme = useContext(ThemeContext);

  return <h1 style={{ color: theme === 'dark' ? '#fff' : '#000' }}>타이틀</h1>;
};

✅ useContext()를 사용하면 타입 추론이 자동으로 되지만, createContext 시 타입이 제대로 지정돼 있어야 정확하게 작동해.


📘 예제 44: Context 기본값의 타입 처리

Context에 undefined를 기본값으로 넣는 경우도 많아. 그럴 땐 null 체크가 필수야.

type AuthContextType = {
  user: string;
  login: () => void;
};

const AuthContext = createContext<AuthContextType | undefined>(undefined);

const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth는 AuthProvider 안에서만 사용해야 합니다.');
  }
  return context;
};

✅ undefined를 기본값으로 하면 잘못된 위치에서 사용할 경우 에러를 던질 수 있어. 커스텀 훅으로 감싸는 게 좋은 패턴이야.