어떤 컴포넌트에서 Provider로 감싸주면 그 하위에 있는 모든 컴포넌트들은 이 React Context에 저장되어 있는 전역 데이터에 접근할 수 있다. 자식 컴포넌트에게 props로 일일이 보내줄 필요가 없다는 것이 가장 큰 장점이다.
value는 context로 관리하고 싶은 데이터를 뜻한다. 이 value의 값을 prop으로 Provider 안에 넣어준다. 이를 통해서 context의 현재 값이 결정된다. 더 자세한 것은 아래에서...!
Context.js
import React, { createContext, useState } from "react";
import FunctionContextComponent from "./FunctionContextComponent";
import ClassContextComponent from "./ClassContextComponent";
export const ThemeContext = createContext(); // export 해 주어야 한다.
export default function Context() {
const [darkTheme, setDarkTheme] = useState(true);
function toggleTheme() {
setDarkTheme((prevDarkTheme) => !prevDarkTheme);
}
return (
<>
{/* value로 전달해준 값을 useContext나 Consumer로 받을 수 있다. */}
<ThemeContext.Provider value={darkTheme}>
<button onClick={toggleTheme}>Toggle Theme</button>
<FunctionContextComponent />
<ClassContextComponent />
</ThemeContext.Provider>
</>
);
}
ClassContextComponent.js
클래스 기반 컴포넌트에서는 Consumer를 이용하여 context를 관리할 수 있다.
import React, { Component } from "react";
import { ThemeContext } from "./Context";
export default class ClassContextComponent extends Component {
themeStyles(dark) {
return {
backgroundColor: dark ? "#333" : "#CCC",
color: dark ? "#CCC" : "#333",
padding: "2rem",
margin: "2rem",
};
}
render() {
return (
<ThemeContext.Consumer> {/* Consumer 활용 */}
{darkTheme => { // value를 props으로 받아와 사용한다.
return <div style={this.themeStyles(darkTheme)}>
ClassTheme
</div>
}}
</ThemeContext.Consumer>
)
}
}
FunctionContextComponent .js
함수 기반 컴포넌트에서는 Consumer를 사용하지 않고, useContext를 사용한다.
useContext를 사용하면 리턴 값으로 value로 전달받은 값을 사용할 수 있다. 위의 클래스 기반 컴포넌트의 사용법과 비교해봤을 때 엄청 코드가 간편해진 것을 확인할 수 있다.
import React, { useContext } from "react";
import { ThemeContext } from "./Context";
export default function FunctionContextComponent() {
const darkTheme = useContext(ThemeContext); // useContext를 통해 ThemeContext의 value를 받아올 수 있다.
const themeStyles = {
backgroundColor: darkTheme ? "#333" : "#CCC", // useContext로 받아온 state를 바로 적용 가능하다.
color: darkTheme ? "#CCC" : "#333",
padding: "2rem",
margin: "2rem",
}
return <div style={themeStyles}>Function Theme</div>;
}
위의 방식을 좀 더 간편하게 하기 위해서 darkTheme이라는 state를 context로 관리할 수 있는 훅을 만들어보자.