[React] Context로 Props Drilling 해결하기

ttining·2025년 4월 4일

React Context : Props Drilling 해결부터 구조적 분리까지


🧩 Context란?

  • React에서 컴포넌트 간 데이터를 전역적으로 공유하기 위한 기능
  • 계층이 깊은 컴포넌트 트리에서도 props 없이 직접 데이터 접근 가능

⚠️ props의 단점 : Props Drilling

  • 부모 → 자식 방향으로만 전달 가능
  • 중간 컴포넌트에서 사용하지도 않는 데이터를 그저 전달만 해야 하는 상황이 발생
  • 유지보수 어려움, 컴포넌트 간 의존도 증가
<App>
  <Layout>
    <Header>
      <UserProfile name="ttining" /> ← 여기서만 필요한 데이터
    </Header>
  </Layout>
</App>
  • 상위에서 받은 name을 중간 컴포넌트가 무의미하게 전달해야 함


🧭 Context의 역할

항목설명
사용 목적중첩된 컴포넌트 트리에서 데이터 공유
해결하는 문제Props Drilling
전달 방식Provider → Consumer 패턴
주요 구성 요소React.createContext, Provider, useContext


🛠️ Context 기본 사용법

// 1. Context 생성
const ThemeContext = React.createContext("light");

// 2. Provider로 값 전달
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Page />
    </ThemeContext.Provider>
  );
}

// 3. Consumer에서 값 사용
function Page() {
  const theme = useContext(ThemeContext);
  return <div>현재 테마: {theme}</div>;
}
  • useContext는 반드시 Provider 하위에서 사용해야 하며,
    그렇지 않으면 undefined가 반환됨 (기본값 설정 가능)


🧱 Context 분리 패턴

  • 실무에서는 Context를 하나의 파일로 분리하는 것이 일반적이다.

📁 디렉토리 구조 예시

src/
  contexts/
    ThemeContext.tsx

📄 ThemeContext.tsx

import { createContext, useContext, useState, ReactNode } from "react";

const ThemeContext = createContext<{
  theme: string;
  setTheme: (t: string) => void;
} | null>(null);

export const ThemeProvider = ({ children }: { children: ReactNode }) => {
  const [theme, setTheme] = useState("light");
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

export const useTheme = () => {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error("useTheme must be used within a ThemeProvider");
  }
  return context;
};
  • useContext를 직접 export하지 않고 useTheme() 같은 커스텀 훅으로 래핑하는 것이 더 안전하고 확장성 있음


⚠️ Context 사용 시 주의점

항목설명
성능 이슈Context의 value가 바뀌면 하위 컴포넌트 전체 리렌더링됨
해결 방법useMemovalue 메모이제이션
Context를 여러 개로 쪼개서 필요할 때만 구독

const value = useMemo(() => ({ theme, setTheme }), [theme]);
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>


✅ Context는 언제 사용할까?

  • 전역적으로 공유되어야 하는 상태일 때
    • 사용자 인증 정보
    • 테마 설정
    • 다국어(locale) 설정
  • 하지만, 자주 변경되는 상태 (예: 입력값, 애니메이션 등)는 Context보다
    Zustand / Redux / recoil 등 상태 관리 라이브러리가 더 적합하다.
profile
내가 보려고 만든 벨로그 *'-'*

0개의 댓글