📌 useContext()
: 상위 컴포넌트에서 제공한 Context 값을 하위 컴포넌트에서 접근할 수 있는 훅
- 상위 컴포넌트에서 ⬇️ 하위 컴포넌트로 데이터를 전달하는 데 사용
- prop drilling(여러 단계의 prop 전달)을 피할 수 있다.
- 사용
- Context 생성: createContext를 사용하여 Context 객체를 생성
- Context 제공: Provider를 사용하여 하위 컴포넌트에 값을 제공
- Context 사용: useContext를 사용하여 Context의 값을 읽어옴
✅ 사용
1️⃣ createContext()
: 새로운 Context 객체를 생성
- 컨텍스트는 기본적으로 데이터를 저장할 수 있는 공간을 만들고, 이 공간을 통해 데이터(상태, 함수 등)를 하위 컴포넌트들에게 전달한다.
- 상위 컴포넌트 or 별도의 컨텍스트 파일에서 컨텍스트 객체를 생성하고, 그 객체를 통해 데이터를 공유할 수 있게 든다.
이 객체를 통해 상태와 메서드를 하위 컴포넌트에 제공할 수 있다⭕ - 생성된 Context 객체는 Provider와 Consumer를 포함한다.
- Provider: Context 값을 제공
- Consumer: Context 값을 소비하는 데 사용
- 사용: 애플리케이션의 전역 상태, 테마, 사용자 인증 정보, 환경 설정 등 여러 컴포넌트에서 공통적으로 사용하는 데이터를 정의할 때
const MyContext = createContext(defaultValue);
- 매개변수
- defaultValue
: Context의 기본값 설정
- 컨텍스트가 제공하는 값이 없는 경우(Context의 Provider가 없을 때), 사용할 기본값을 설정할 수 있다.
(ex. 초기값, null, 빈 객체 등)
- 컨텍스트가 제공하는 값이 없는 경우(Context의 Provider가 없을 때), 사용할 기본값을 설정할 수 있다.
- defaultValue
// UserContext.js
import { createContext } from 'react';
const UserContext = createContext(); // 기본값 없음
export default UserContext;
// 기본값 설정 -------------------------------
const ThemeContext = createContext('light'); // 기본값은 'light'
2️⃣ Provider
: 상위 컴포넌트에서 하위 컴포넌트로 Context 값을 제공하는 컴포넌트
- 상위 컴포넌트에서 컨텍스트 객체의 value prop으로 하위 컴포넌트들에게 Context 값을 전달
Context 객체.Provider value={/* 하위 컴포넌트에 전달할 데이터(context value) */}>
{/* 하위 컴포넌트(children components) */}
</Context 객체.Provider>
- 매개변수
- context value
: 하위 컴포넌트에 전달할 데이터
- Context를 사용하는 하위 컴포넌트들에서 접근할 수 있다.
- children components
: 하위 컴포넌트
- context value
// App.js
import React from 'react';
import UserContext from './UserContext';
import UserProfile from './UserProfile';
function App() {
const user = { name: 'Alice', age: 25 };
return (
<UserContext.Provider value={user}>
<UserProfile />
</UserContext.Provider>
);
}
export default App;
3️⃣ useContext()
: 하위 컴포넌트에서 Context 값을 읽어오는 훅
- createContext로 생성한 컨텍스트의 값을 사용하기 위해 호출되는 훅
- useContext에 Context 객체를 전달하면, 해당 Context의 Provider가 제공한 값을 반환한다.
- 해당 값이 업데이트되면 해당 값을 사용하는 모든 컴포넌트가 리렌더링 된다.
- 사용: 트리 구조에서 깊숙이 위치한 컴포넌트들이 상위 컴포넌트로부터 props를 거치지 않고 데이터를 필요로 할 때
const contextValue = useContext(Context);
- 매개변수
- Context
: Context 객체
- createContext로 생성한 컨텍스트 객체를 전달
- Context
// UserProfile.js
import React, { useContext } from 'react';
import UserContext from './UserContext';
function UserProfile() {
const user = useContext(UserContext);
return (
<div>
<h1>User Profile</h1>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
</div>
);
}
export default UserProfile;
예제 1. 테마(Theme) 컨텍스트
ThemeContext.js
- createContext()를 호출하여 ThemeContext 객체를 생성한다.
import { createContext } from 'react';
// 1. Context 객체 생성
const ThemeContext = createContext(); // 기본값을 설정하지 않으면 undefined
export default ThemeContext;
App.js
- ThemeContext.Provider를 사용하여 테마와 테마를 변경하는 함수를 제공, value prop으로 전달한다.
- useState를 사용하여 테마 상태를 관리하고, toggleTheme 함수로 테마를 변경한다.
import React, { useState } from 'react';
import ThemeContext from './ThemeContext'; // 생성한 Context 객체를 import
import ThemeSwitcher from './ThemeSwitcher'; // 하위 컴포넌트
import ThemedComponent from './ThemedComponent'; // 하위 컴포넌트
function App() {
const [theme, setTheme] = useState('light'); // 테마 상태를 설정
// 테마를 토글하는 함수
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
// 2. Provider를 사용하여 하위 컴포넌트에게 테마 제공
<ThemeContext.Provider value={{ theme, toggleTheme }}>
<div style={{ padding: '20px' }}>
<h1>Theme Context Example</h1>
<ThemeSwitcher />
<ThemedComponent />
</div>
</ThemeContext.Provider>
);
}
export default App;
ThemeSwitcher.js
- useContext(ThemeContext)를 사용하여 테마와 테마를 변경하는 함수를 읽어온다.
- 버튼 클릭 시 테마를 변경하는 기능을 제공한다.
import React, { useContext } from 'react';
import ThemeContext from './ThemeContext'; // 생성한 Context 객체를 import
function ThemeSwitcher() {
const { theme, toggleTheme } = useContext(ThemeContext); // 3. Context 값 사용
return (
<div>
<p>Current theme: {theme}</p>
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'dark' : 'light'} mode
</button>
</div>
);
}
export default ThemeSwitcher;
ThemedComponent.js
- useContext(ThemeContext)를 사용하여 현재 테마를 읽어온다.
- 이 테마에 따라 컴포넌트의 스타일을 변경한다.
import React, { useContext } from 'react';
import ThemeContext from './ThemeContext'; // 생성한 Context 객체를 import
function ThemedComponent() {
const { theme } = useContext(ThemeContext);
// 스타일을 테마에 따라 설정
const style = {
backgroundColor: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#000' : '#fff',
padding: '10px',
borderRadius: '5px'
};
return (
<div style={style}>
<h2>This is a {theme} themed component!</h2>
</div>
);
}
export default ThemedComponent;