다음은 React Reference 에 있는 useContext 에 대한 설명이다.
context 객체(React.createContext에서 반환된 값)을 받아 그 context의 현재 값을 반환합니다. · · ·
Context 객체에서 값을 받아서 사용한다는 내용인데, useContext 를 설명하기 앞서 React Context 에 대한 이해가 먼저 필요한 것 같다...!
공식문서에는 "context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다." 라고 적혀있다.
일반적인 React 애플리케이션에서 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달할 때는 props 를 통해서 전달된다.
만약 다음과 같은 구조에서 Grand Child 1 컴포넌트에서 사용하고 싶은 데이터가 있으면 Parent1 컴포넌트에서 데이터를 받아서 Grand Child 1 에 이르기까지 props 를 전달해서 사용해야 한다. child 컴포넌트에서 데이터를 사용하지 않아도 Grand Child 1 컴포넌트에서 데이터를 사용하기 위해서는 props 를 받아서 전달해야 한다는 것이다.
뭐 이정도야 하고 넘어갈 수도 있겠지만 만약 위의 사진보다 훨씬 깊은 구조를 가지고 있는 컴포넌트라면? 매번 props 를 전달해야 하는 번거로움이 있기 때문에 Context 객체를 사용하는 것이다.
Context 를 사용하게 되면 Context 라는 별도의 공간에 전역적으로 데이터를 저장하기 때문에 부모 컴포넌트에서 자식컴포넌트로 매번 props 를 전달하지 않고 데이터를 필요로하는 컴포넌트에서만 Context 객체에서 필요한 데이터를 가져서 쓸 수 있게 되는 편리함을 갖게 된다.
React Context 를 사용하기 위해서는 세 가지 핵심 개념을 알고 있어야한다.
createContext
: Context 객체를 만든다.Provider
: 생성된 Context 의 props 를 하위 컴포넌트에 전달하는 역할을 한다.Consumer
: Context 의 변화를 감시하는 역할을 한다.예제를 통해 Context 를 사용하는 방법을 알아보자.
import React, { createContext } from "react";
import Children from "./Children";
// Context 객체를 생성한다.
export const AppContext = createContext();
const App = () => {
const user = {
name: "홍길동",
age: 25,
};
return (
<>
// AppContext 로 Children 컴포넌트를 감싸면 AppContext 하위의 컴포넌트에서
// value 를 사용할 수 있게 된다.
<AppContext.Provider value={user}>
<div>
<Children />
</div>
</AppContext.Provider>
</>
);
};
export default App;
import React from "react";
import { AppContext } from "./App";
const Children = () => {
return (
<AppContext.Consumer>
{(user) => (
<>
<h3>user의 이름은 {user.name}입니다.</h3>
<h3>user의 나이는 {user.age}입니다.</h3>
</>
)}
</AppContext.Consumer>
);
};
export default Children;
위와 같이 Context 를 사용하게되면 컴포넌트가 직접 props 를 전달받지 않고 AppContext 객체 안에있는 user 데이터를 전달받아서 사용할 수 있게된다.
그렇다면 useContext 는 왜 사용하는 것일까?
import React, { useContext } from "react";
import { AppContext } from "./App";
const Children = () => {
const user = useContext(AppContext);
return (
<>
<h3>user의 이름은 {user.name}입니다.</h3>
<h3>user의 나이는 {user.age}입니다.</h3>
</>
);
};
export default Children;
useContext 를 적용하게 되면 return 구문에서 <AppContext.Consumer>
같은 태그를 작성해야되는 불편함이 줄어들고 context 를 불러온 후 변수에 저장해서 바로 사용할 수 있게 된다.