context를 이용하면 단계마다 일일이 props
를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다.
context는 React 컴포넌트 트리 안에서 전역적(global)이라고 볼 수 있는 데이터를 공유할 수 있도록 고안된 방법이다. 예를 들어, 현재 로그인한 유저, 테마, 선호하는 언어 등을 필요로 하는 자식 데이터에 바로 전달해줄 수 있다.
App.js에 있는 isChange
상태와 changeMode
이벤트 핸들러는 Header.js에서 필요로 한다. 그러나 컴포넌트 구조가 App.js -> AllTodoList.js -> Header.js 로 되어 있기 때문에 props를 필요로 하지 않는 AllTodoList.js를 거쳐야 한다.
하지만 context Api를 사용하면 중간에 AllTodoList.js를 거치지 않고 바로 Header.js에서 isChange
와 changeMode
를 사용할 수 있다.
createContext()
함수를 사용하여 context
를 생성한다.
아래와 같이 별도로 디렉토리를 만들어도 되고 최상위 컴포넌트에서 만들어도 상관 없다.
context의 이름은 아무거나 지정해도 되며, 하위에서 import
할 수 있게 export
해준다.
// theme.js
import { createContext } from "react"
export const ThemeContext = createContext(null);
생성한 context
를 import
한 후, 최상위 컴포넌트를 Provider
로 감싸준다.
전달할 value = {}
안에 객체 형태로 담아준다.
// App.js
import { ThemeContext } from './theme';
function App() {
const [isChange, setIsChange] = useState(false);
const changeMode = () => {
setIsChange(!isChange);
}
return (
<ThemeContext.Provider value={{ isChange, changeMode }}>
<ThemeProvider theme={isChange ? darkTheme : lightTheme}>
<div className="App">
<GlobalStyle />
<Routes>
<Route path='/' element={<AllTodoList />} />
</Routes>
</div>
</ThemeProvider>
</ThemeContext.Provider>
);
}
export default App;
useContext
Hook과 생성한 context
를 import
한 후 useContext
를 사용하여 value
값을 가져온다.// Header.js
import { useContext } from 'react';
import { ThemeContext } from '../theme';
function Header() {
const { isChange, changeMode } = useContext(ThemeContext);
return (
<HeaderContainer>
<ModeChangeButton>
<FontAwesomeIcon icon={isChange ? faMoon : faSun} size="lg" onClick={changeMode} />
</ModeChangeButton>
</HeaderContainer>
);
}
export default Header;