리액트/기초
✨ React Context : createContext, Provider, useContext란?
lamarcK
2025. 4. 20. 09:51
React Context는 컴포넌트 트리를 통해 데이터를 직접 전달할 수 있는 시스템이다. props drilling 문제를 해결하기 위한 React의 내장 기능이다.
택배 시스템에 비유하면 다음과 같다.
- createContext = 택배 회사 설립
- Provider = 물품을 포장하고 배송을 시작하는 지점
- useContext = 택배 물품을 수령하는 곳
주요 구성 요소
1. createContext()
Context 객체를 생성하는 함수
const MessageContext = React.createContext();
2. Context.Provider
생성된 Context를 통해 데이터를 제공하는 컴포넌트
function App() {
return (
<MessageContext.Provider value="Hello">
<ChildComponent />
</MessageContext.Provider>
);
}
3. useContext()
Context의 값을 사용하는 Hook
function ChildComponent() {
const message = useContext(MessageContext);
return <div>{message}</div>;
}
실제 사용 예시
// 1. Context 생성
const ThemeContext = React.createContext();
// 2. Provider로 값 제공
function App() {
const theme = {
dark: {
background: 'black',
color: 'white'
}
};
return (
<ThemeContext.Provider value={theme}>
<Header />
<MainContent />
</ThemeContext.Provider>
);
}
// 3. Context 값 사용
function Header() {
const theme = useContext(ThemeContext);
return (
<header style={theme.dark}>
헤더
</header>
);
}
주요 사용 사례
- 전역 테마 관리 (다크모드/라이트모드 전환, UI 색상 테마)
- 사용자 인증 정보 (로그인 상태, 사용자 권한, 토큰 관리)
- 언어 설정 (다국어 지원, i18n 설정, 지역화)
- 전역 상태 관리 (장바구니 정보, 알림 메시지, 사이드바 상태)
- 환경 설정 (앱 설정, 사용자 기본 설정)
- API 클라이언트 공유 (axios 인스턴스, API 엔드포인트)
- 라우터 정보 (현재 경로, 네비게이션 상태)
- 미디어 쿼리 정보 (반응형 디자인 상태, 화면 크기)
- 폼 컨텍스트 (폼 유효성 검사, 폼 상태 관리)
- 모달/팝업 관리 (전역 모달 상태, 알림창 관리)
장점
- Props Drilling 방지
- Props Drilling : 상위 컴포넌트의 데이터를 하위 컴포넌트로 전달하기 위해 중간 컴포넌트들을 거쳐가는 현상
- 프롭스를 특정 컴포넌트에 직접적으로 전달하지 못하고 상속에 상속을 거쳐서 정보를 전달하는 경우 발생
- 컴포넌트 간 데이터 공유 용이
- 이중 상속, 중첩 상속을 하지 않고 다양한 컴포넌트가 데이터를 받아다 쓸 수 있다.
**기존 Props 방식 function App() { const data = "공유 데이터"; return ( <div> <A data={data} /> <B data={data} /> <C> <D data={data} /> </C> </div> ); }
**Context 방식 const DataContext = createContext(); function App() { const data = "공유 데이터"; return ( <DataContext.Provider value={data}> <A /> {/* props 전달 불필요 */} <B /> {/* 직접 접근 가능 */} <C> <D /> {/* 중첩된 컴포넌트도 바로 접근 */} </C> </DataContext.Provider> ); } // 어떤 컴포넌트에서든 바로 사용 가능 function D() { const data = useContext(DataContext); return <div>{data}</div>; }
- 이중 상속, 중첩 상속을 하지 않고 다양한 컴포넌트가 데이터를 받아다 쓸 수 있다.
- 전역 상태 관리 가능
- Provider로 감싼 컴포넌트들은 createContext()를 만든 컴포넌트에서 제공한 정보에 UserContext로 접근이 가능하다.
// UserContext.js const UserContext = createContext(); // Context 생성 // App.js function App() { const userInfo = { // Provider가 제공할 정보 name: "Kim", age: 25 }; return ( <UserContext.Provider value={userInfo}> <Header /> {/* userInfo 접근 가능 */} <MainContent /> {/* userInfo 접근 가능 */} <Footer /> {/* userInfo 접근 가능 */} </UserContext.Provider> ); } // 어떤 하위 컴포넌트든 접근 가능 function Header() { const userInfo = useContext(UserContext); return <div>{userInfo.name}</div>; }
- Provider로 감싼 컴포넌트들은 createContext()를 만든 컴포넌트에서 제공한 정보에 UserContext로 접근이 가능하다.
주의사항
- 과도한 사용 지양
- 성능 영향 고려
- 컴포넌트 재사용성 감소 가능성
권장 사용 패턴
- 전역적으로 필요한 데이터에만 사용
- 변경이 적은 데이터에 적합
- 필요한 범위만큼만 Provider 적용