Context는 리액트 컴포넌트 간에 어떠한 값을 공유할 수 있게 해 주는 기능이다. 주로 Context는 전역적으로 필요한 값을 다룰 때 사용한다. (꼭 전역적일 필요는 없다.) Context를 단순하게 리액트 컴포넌트에서 Props가 아닌 또 다른 방식으로 컴포넌트 간에 값을 전달하는 방법이라고 생각하면 된다.
리액트 앱에서는 일반적으로 컴포넌트에게 데이터를 전달해 주어야 할 때 Props를 통해 전달한다. 그런데 깊숙히 위치한 컴포넌트에 데이터를 전달해야 하는 경우에는 여러 컴포넌트를 거쳐 연달아서 Props를 설정해 주어야 하기 때문에 불편하고 실수할 가능성이 높아진다.
function App() {
return <GrandParent value="Hello World!" />;
}
function GrandParent({ value }) {
return <Parent value={value} />;
}
function Parent({ value }) {
return <Child value={value} />;
}
function Child({ value }) {
return <GrandChild value={value} />;
}
function GrandChild({ value }) {
return <Message value={value} />;
}
function Message({ value }) {
return <div>Received: {value}</div>;
}
이러한 코드를 Props Drilling이라고 부른다. 또한, 여러 종류의 자식 컴포넌트가 특정 값에 의존한다고 가정한다면, 이는 많이 복잡해 보이고 가독성이 떨어진다는 단점이 있다.
Context를 사용하여 해결해 보자.
Context는 리액트 패키지에서 createContext라는 함수를 불러 와서 생성할 수 있다.
import { createContext } from 'react';
const MyContext = createContext();
Context는 객체다. 이 객체 안에는 Provider라는 컴포넌트가 들어 있다. 그리고, 그 컴포넌트 간에 공유하고자 하는 값을 value라는 props로 설정하면 자식 컴포넌트에서 해당 값에 바로 접근할 수 있다.
function App() {
return (
<MyContext.Provider value="Hello World">
<GrandParent />
</MyContext.Provider>
);
}
이렇게 하면 원하는 컴포넌트에서 useContext라는 리액트 훅을 사용하여 Context에 넣은 값에 바로 접근할 수 있다. 해당 훅의 인자에는 createContext로 만든 MyContext를 넣는다.