useContext함수는 전역적으로 상태관리를 할 수 있는 도구이다. useContext는 전역적으로 상태를 관리하기에 props를 통해 많은 데이터를 전달하거나 잘못된 부분을 수정할 때 복잡한 과정을 줄여줄 수 있는 장점이 있다.
createContext 함수 import 후 상태관리를 할 값(보통은 객체)을 넣어주면 컨텍스트 객체 생성이 완료된다. createContext에서 반환반은 값은 컴포넌트가 되거나, 컴포넌트를 포함하는 객체가 된다. 컴포넌트를 렌더링 할 때 리액트 트리 상위에서 가장 가까이 있는 Provider
로부터 현재 값을 읽음
// src/store/theme-context.js
import { createContext } from 'react';
const ThemeContext = createContext(defaultValue)
// ThemeContext가 컴포넌트는 아니지만 컴포넌트를 포함할 객체이기에
// 파스칼 케이스로 명명함
export default ThemeContext;
defaultValue매개변수는 트리 안에서 적절한 Provider를 찾이 못했을 때만 쓰이는 값이다. (현실적으로는 컴포넌트를 독립적으로 테스트할 때 유용한 값임)
특정 컴포넌트를 포함한 하위의 모든 컴포넌트의 상태값을 바꾸고 싶을 때는 특정 컴포넌트를 포함하고 있는 부모 컴포넌트의 <Context.Provider> 태그로 감싸주고 value 속성을 추가해 값을 바꾸어 주면 Provider 하위에 있는 컴포넌트 안에서 useContext가 반환하는 값이 Provider의 값과 같아진다.
import ThemeContext from './theme-context';
const ThemeContextProvider = (props) => {
const themeContext = { border: '10px solid red' };
return (
<ThemeContext.Provider value={themeContext}>
{props.children}
</ThemeContext.Provider>
);
};
export default ThemeContextProvider;
// App.js
import { useContext } from 'react';
import { Helmet } from 'react-helmet';
import classes from './App.module.css';
import ThemeContext from './store/theme-context';
import ThemeContextProvider from './store/ThemeProvider';
const App = (props) => {
return (
<ThemeContextProvider>
<div className={classes.root}>
<Helmet htmlAttributes={{ lang: 'ko' }} />
<h1>Hello World</h1>
<Sub1 />
</div>
</ThemeContextProvider>
);
};
function Sub1() {
const theme = useContext(ThemeContext);
return (
<div style={theme}>
<h1>Sub1</h1>
<Sub2 />
</div>
);
}
function Sub2() {
return (
<div>
<h1>Sub2</h1>
<Sub3 />
</div>
);
}
function Sub3(props) {
const themeCtx = useContext(ThemeContext);
return (
<div style={themeCtx}>
<h1>Sub3</h1>
</div>
);
}
export default App;
<<MyContext.Consumer>
{(ctx) => return (/* context 값을 이용한 렌더링 */)}
</MyContext.Consumer>
Context.Consumer의 자식은 함수여야 한다. 이 함수는 context의 현재값을 받고 리액트 노드를 반환한다. 이 함수가 받는 ctx 매개변수 값은 해당 context의 Provider 중 상위 트리에서 가장 가까운 Provider의 ctx props와 동일하다.