개요
createContext
는 컴포넌트 트리에서 값을 깊게 전달할 때 props를 일일이 넘기지 않고, context로 제공/구독할 수 있게 해주는 API입니다. context를 생성하면, Provider로 값을 공급하고, 하위 컴포넌트에서 useContext로 값을 읽을 수 있습니다.
const SomeContext = createContext(defaultValue);
Reference
createContext(defaultValue)
컴포넌트 외부(모듈 스코프)에서 context를 생성합니다.
- 파라미터
defaultValue
: 상위에 Provider가 없을 때 사용할 기본값. 의미 있는 기본값이 없다면null
을 지정하세요. 이 값은 "최후의 수단"으로만 사용되며, 동적으로 바뀌지 않습니다.
- 반환값
- context 객체. 이 객체 자체는 정보를 담지 않으며, 어떤 context를 읽고/제공할지 식별자 역할만 합니다.
- 주요 프로퍼티:
SomeContext.Provider
: context 값을 공급하는 Provider 컴포넌트SomeContext.Consumer
: (legacy) context 값을 읽는 Consumer 컴포넌트
SomeContext.Provider
Provider로 감싼 하위 트리 전체에 context 값을 공급합니다.
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={theme}>
<Page />
</ThemeContext.Provider>
);
}
- props
value
: 하위에서 읽을 context 값(타입 제한 없음). 가장 가까운 Provider의 값을 하위에서 읽게 됩니다.
SomeContext.Consumer
(legacy)
useContext가 도입되기 전 context 값을 읽는 방식입니다. 새 코드는 useContext를 사용하세요.
function Button() {
// 🟡 권장하지 않는 방식
return (
<ThemeContext.Consumer>
{theme => <button className={theme} />}
</ThemeContext.Consumer>
);
}
- props
children
: 함수. 현재 context 값을 인자로 받아 반환값을 렌더링합니다. context 값이 바뀌면 함수가 다시 호출되어 UI가 갱신됩니다.
사용법
context 생성 및 사용
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext('light');
const AuthContext = createContext(null);
function Button() {
const theme = useContext(ThemeContext);
// ...
}
function Profile() {
const currentUser = useContext(AuthContext);
// ...
}
function App() {
const [theme, setTheme] = useState('dark');
const [currentUser, setCurrentUser] = useState({ name: 'Taylor' });
return (
<ThemeContext.Provider value={theme}>
<AuthContext.Provider value={currentUser}>
<Page />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
- Provider로 감싼 하위 트리에서는 언제든 useContext로 값을 읽을 수 있습니다.
- context 값이 바뀌면, 해당 값을 읽는 모든 컴포넌트가 자동으로 리렌더링됩니다.
context 파일 분리 및 공유
여러 파일에서 context를 공유하려면 별도 파일에 선언 후 export/import 하세요.
// Contexts.js
import { createContext } from 'react';
export const ThemeContext = createContext('light');
export const AuthContext = createContext(null);
// Button.js
import { ThemeContext } from './Contexts.js';
function Button() {
const theme = useContext(ThemeContext);
// ...
}
// App.js
import { ThemeContext, AuthContext } from './Contexts.js';
function App() {
// ...
return (
<ThemeContext.Provider value={theme}>
<AuthContext.Provider value={currentUser}>
<Page />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
트러블슈팅
context 값이 바뀌지 않는 경우
createContext('light')
처럼 context 생성 시 지정한 값은 "기본값"일 뿐, Provider가 없을 때만 사용됩니다. context 값을 동적으로 바꾸려면 반드시 Provider로 감싸고, value props에 state 등을 전달해야 합니다.
참고 및 주의사항
- context는 깊은 트리 구조에서 props drilling을 피할 때 유용합니다.
- context 값이 자주 바뀌면, 값을 읽는 모든 컴포넌트가 리렌더링되므로 성능에 주의하세요.
- Consumer 방식은 legacy이므로, 새 코드는 useContext를 사용하세요.
- context 객체 자체에는 값이 저장되지 않으며, Provider/Consumer/useContext를 통해서만 값을 주고받습니다.
반응형