ReactReact 기초강의 10개 중 7번째난이도 기초

Context API — 전역 상태 공유

발행 읽는 시간 약 1 분

  • React
  • Context
  • useContext
  • 전역상태
  • PropDrilling

강의 소개

Context API로 prop drilling 없이 컴포넌트 트리 어디서나 데이터를 공유하는 방법을 배웁니다. 테마, 인증, 언어 설정 등 전역 상태 관리에 활용합니다.

Prop Drilling 문제#

Diagram · Mermaid

Context를 쓰면 중간 단계 없이 직접 전달할 수 있습니다.


Context 만들기#

TSX
// src/contexts/AuthContext.tsx
import { createContext, useContext, useState, ReactNode } from "react";

interface User {
    id: string;
    name: string;
    email: string;
    role: "admin" | "user";
}

interface AuthContextValue {
    user: User | null;
    login: (email: string, password: string) => Promise<void>;
    logout: () => void;
    isLoading: boolean;
}

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

// 커스텀 훅으로 컨텍스트 사용 간소화
export function useAuth() {
    const context = useContext(AuthContext);
    if (!context) throw new Error("useAuth는 AuthProvider 안에서 사용해야 합니다.");
    return context;
}

export function AuthProvider({ children }: { children: ReactNode }) {
    const [user, setUser] = useState<User | null>(null);
    const [isLoading, setIsLoading] = useState(false);

    async function login(email: string, password: string) {
        setIsLoading(true);
        try {
            const response = await fetch("/api/auth/login", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({ email, password }),
            });
            const data = await response.json();
            setUser(data.user);
        } finally {
            setIsLoading(false);
        }
    }

    function logout() {
        setUser(null);
    }

    return (
        <AuthContext.Provider value={{ user, login, logout, isLoading }}>
            {children}
        </AuthContext.Provider>
    );
}

Provider로 감싸기#

TSX
// src/main.tsx
import { AuthProvider } from "./contexts/AuthContext";

createRoot(document.getElementById("root")!).render(
    <StrictMode>
        <AuthProvider>
            <App />
        </AuthProvider>
    </StrictMode>
);

어디서나 사용#

TSX
// 어떤 깊이의 컴포넌트에서든
function UserAvatar() {
    const { user } = useAuth();

    if (!user) return null;
    return <img src={`/avatars/${user.id}`} alt={user.name} />;
}

function LogoutButton() {
    const { logout } = useAuth();
    return <button onClick={logout}>로그아웃</button>;
}

function AdminPanel() {
    const { user } = useAuth();

    if (user?.role !== "admin") return <p>접근 권한이 없습니다.</p>;
    return <div>관리자 패널</div>;
}

테마 Context 예시#

TSX
// src/contexts/ThemeContext.tsx
type Theme = "light" | "dark";

interface ThemeContextValue {
    theme: Theme;
    toggleTheme: () => void;
}

const ThemeContext = createContext<ThemeContextValue>({
    theme: "light",
    toggleTheme: () => {},
});

export function useTheme() {
    return useContext(ThemeContext);
}

export function ThemeProvider({ children }: { children: ReactNode }) {
    const [theme, setTheme] = useState<Theme>("light");

    useEffect(() => {
        document.documentElement.setAttribute("data-theme", theme);
    }, [theme]);

    const toggleTheme = () => setTheme(t => t === "light" ? "dark" : "light");

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

// 사용
function DarkModeToggle() {
    const { theme, toggleTheme } = useTheme();
    return (
        <button onClick={toggleTheme}>
            {theme === "light" ? "🌙 다크모드" : "☀️ 라이트모드"}
        </button>
    );
}

Context 성능 고려#

TSX
// 분리되지 않은 Context — 일부만 바뀌어도 전체 구독자 리렌더링
const UserContext = createContext({ user, settings, notifications });

// ✅ 분리된 Context — 각각 독립 업데이트
const UserContext = createContext(user);
const SettingsContext = createContext(settings);
const NotificationsContext = createContext(notifications);

정리#

Diagram · Mermaid
개념설명
createContextContext 생성
Provider값을 하위 트리에 제공
useContextContext 값 소비
커스텀 훅useAuth, useTheme 등 사용성 개선

다음 편에서는 커스텀 훅 — 로직을 재사용 가능한 훅으로 추출하는 방법을 배웁니다.

Follow · Ask · Work

이 글이 도움이 됐다면

짧은 작업 기록과 데모는 인스타그램에 올립니다. 만들고 싶은 것이 있다면 프로젝트 의뢰나 협업 제안도 편하게 보내 주세요.

글쓴이

파란여우

직접 만든 AI 앱·제품의 개발·배포를 공개하는 실전형 테크 크리에이터

파란여우 소개 Instagram @bluefox._.hi

이어서 보기

만들고 싶은 것이 있다면 프로젝트 의뢰로 알려 주세요.