컴포넌트가 아닌 전역적으로 상태를 관리하고 싶을 때, 사용한다.
# contexts/User.js
import { createContext } from 'react';
const UserContext = createContext({ name: 'DARTZ'});
export default UserContext;
위와 같이 createContext를 사용해서 전역으로 사용하고 싶은 변수나 함수를 저장한다.
Consumer 컴포넌트는 상위 컴포넌트 중 가장 가까운 곳에 있는 Provider 컴포넌트가 전달하는 데이터를 이용한다. 만약에 Provider가 없다면 createContext 함수의 파라미터로 전달 된 기본값을 사용한다.
# components/User.js
import UserContext from '../contexts/User'
const User = () => {
return (
<UserContext.Consumer>
{value => <Text>{value.name}</Text>}
</UserContext.Consumer>
)
하위 컴포넌트에 Context의 변화를 알리는 역할을 한다.
Provider 컴포넌트는 value를 받아서 모든 하위 컴포넌트에 전달하고, 하위 컴포넌트는 Provider 컴포넌트의 value가 변경될 때마다 다시 렌더링된다.
# src/App.js
import UserContext from './contexts/User';
const App = () => {
return (
<UserContext.Provider value={{ name: 'Dartz' }}>
<User />
</UserContext.Provider>
)
}
Provider 컴포넌트를 사용할 때, 반드시 value를 지정해야 한다는 점과 Consumer 컴포넌트는 가장 가까운 Provider 컴포넌트가 전달하는 값을 이용한다는 점을 꼭 기억해야한다.
# context/Progress.js
import React, { useState, createContext } from "react";
const ProgressContext = createContext({
inProgress: false,
spinner: () => {},
});
function ProgressProvider({ children }) {
const [inProgress, setInProgress] = useState(false);
const spinner = {
start: () => setInProgress(true),
stop: () => setInProgress(false),
};
const value = { inProgress, spinner };
return (
<ProgressContext.Provider value={value}>
{children}
</ProgressContext.Provider>
);
}
export { ProgressContext, ProgressProvider };
# src/App.js
import { ProgressProvider, UserProvider } from "./context";
function App() {
return (
<ProgressProvider>
<UserProvider>
<Navigation />
</UserProvider>
</ProgressProvider>
);
}
export default App;
Consumer 대신 useContext Hook을 사용해 Context 값을 사용할 수 있다.
...
const { dispatch } = useContext(UserContext);
const { spinner } = useContext(ProgressContext);
const [text, setText] = useState('')
const _handleLoginButtonPress = () => {
spinner.start()
spinner.stop();
};
Context는 애플리케이션 전체에서 알고 있어야 하는 로그인 상태를 관리하거나, 애플리케이션의 테마 혹은 설정 상태를 관리할 때 유용하게 사용할 수 있다. 무분별한 사용은 금지!