useContext
는 전역 상태 공유에 사용되는 훅이야. Redux 없이도 간단한 상태를 여러 컴포넌트에서 공유할 수 있어.
TypeScript와 함께 사용할 때는 Context의 타입 정의가 핵심이야.
import { createContext } from 'react';
type Theme = 'light' | 'dark';
const ThemeContext = createContext<Theme>('light');
✅ createContext<Type>(defaultValue) 형식으로 타입을 지정해줘야 useContext 사용할 때 타입 추론이 정확해져.
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 컴포넌트로 감싸야 실제 값이 자식 컴포넌트에 전달돼. 기본값만으로는 상태가 바뀌지 않아.
useContext
훅으로 사용import { useContext } from 'react';
const Header = () => {
const theme = useContext(ThemeContext);
return <h1 style={{ color: theme === 'dark' ? '#fff' : '#000' }}>타이틀</h1>;
};
✅ useContext()를 사용하면 타입 추론이 자동으로 되지만, createContext 시 타입이 제대로 지정돼 있어야 정확하게 작동해.
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를 기본값으로 하면 잘못된 위치에서 사용할 경우 에러를 던질 수 있어. 커스텀 훅으로 감싸는 게 좋은 패턴이야.