[React] 32. Context 사용하기

서회정's avatar
Mar 09, 2026
[React] 32. Context 사용하기

 
Props Drilling이 발생하고 있는 컴포넌트에게
Context를 사용하여 문제점을 개선해보자.
 
먼저 저번 시간에도 활용했던 투두리스트 앱을 활용해보자.
 

1. Props Drilling 발생 지점 찾기

 
현재 투두리스트에서 발생하고 있는 Props Drilling을
살펴보자.
 
App컴포넌트에서 만든 onUpdateonDelete함수는
최종적으로 TodoItem 컴포넌트에 전달되어야하는데
그러기 위해 List컴포넌트에게 먼저 props로 전달되고
List컴포넌트에서 다시 props로 TodoItem까지 전달된다.
 
이 과정에서 Props Drilling이 발생하고있다.
 
notion image
notion image
 
notion image
notion image
 

2. Context 생성

 
먼저 컨텍스트를 사용하기 위해서는 새로운 컨텍스트를 만들어야한다.
createContext를 App컴포넌트에서 불러오자.
 
notion image
 
새로운 컨텍스트 객체 생성해주자.
이 때 컨텍스트 객체를 생성하는 곳은 컴포넌트 외부이다.
 
컨텍스트의 역할은 단순히 데이터를 하위에 있는 컴포넌트에게
전달해주기만 하면 되는데 계속해서 리렌더링 할 필요가 없기 때문이다.
 
const TodoContext = createContext();
 
컨텍스트를 사용해보기 전에 이렇게 만들어진
컨텍스트 객체에 어떤 값들이 있는지 콘솔에 출력해서 살펴보자.
 
아래 이미지에서 확인할 수 있듯 컨텍스트는 여러 값을
가지고 있는데 그 중에서도 우리가 중요하게 볼 것은
Provider라는 프로퍼티이다.
 
프로바이더는 공급자라는 뜻으로 이 컨텍스트가 공급할
데이터를 설정하거나 이 컨텍스트의 데이터를 공급받을
컴포넌트를 설정하는 역할을 한다.
 
notion image
 
이러한 프로바이더는 컴포넌트로서 사용할 수 있다.
 
App컴포넌트에서 props를 전달받고 있는
두 컴포넌트를 감싸는 형태로 사용할 수 있다.
 
<div className="App"> <Header /> <TodoContext.Provider> <Editor onCreate={onCreate} /> <List todos={todos} onUpdate={onUpdate} onDelete={onDelete} /> </TodoContext.Provider> </div>
 
여기까지 바꾼 뒤 컴포넌트의 계층을 살펴보자.
기존에 우리 앱의 컴포넌트 계층은 다음과 같은 구조였다.
 
notion image
 
여기서 TodoContext객체를 만들고,
TodoContext.Provider컴포넌트에게 Provider 설정을 했다.
 
그럼 다음 이미지처럼 프로바이더 컴포넌트로 묶은
컴포넌트들은 App이 아닌 프로바이더의 하위 컴포넌트가 된다.
 
notion image
 
그리고 프로바이더 컴포넌트의 value속성으로
props로 전달했던 요소들을 객체 형태로 넣어주면
컨텍스트로 하위에 있는 모든 컴포넌트에게 전달할 수 있게 된다.
 
<TodoContext.Provider value={{ todos, onCreate, onUpdate, onDelete, }} > <Editor /> <List /> </TodoContext.Provider>;
 
notion image
 
프로바이더로 감싼 상위 컴포넌트 뿐만 아니라
상위에 있는 컴포넌트의 아래에 존재하는 모든 컴포넌트에
직접적으로 데이터를 공급할 수 있다!
 
notion image
 
따라서 TodoItem도 프로바이더에게 직접 데이터를
전달받을 수 있게 된다.
 
notion image
 
실제로 프로바이더 컴포넌트는 value에 객체의 형태로
전달받은 props의 모든 값이 잘 들어가 있다.
 
notion image

3. Context로 데이터 공급받기

 
그럼 이제 데이터를 공급받을 컴포넌트를 살펴보자.
 

1. Editor 컴포넌트

 
먼저 onCreate 함수를 전달받던 Editor컴포넌트부터 시작하자.
우선 props로 전달받던 값들은 이제 삭제해주자.
 
// <Editor onCreate={onCreate} /> <Editor />
 
그리고 Editor컴포넌트에서 받던 props도 삭제하고
useContext 훅을 추가해주자.
 
notion image
 
그리고 컨텍스트를 호출하여 인수로는 우리가 데이터를
전달받을 컨텍스트의 이름을 직접 적으면 된다.
 
const data = useContext(TodoContext);
 
이를 data라는 변수에 저장해서 콘솔에 출력하면
TodoContext에서 받을 수 있는 모든 데이터가 나타나는데
Editor컴포넌트에서 사용할 데이터만 구조분해할당 문법으로 받아주자.
 
notion image
 
const { onCreate } = useContext(TodoContext);
 
추가 기능이 잘 된다!
 
notion image
 

2. List 컴포넌트

 
ListTodoItem 컴포넌트에도 컨텍스트로
값을 전달해주자.
 
먼저 List 컴포넌트에 전달하던 props를 제거하자.
 
// <List todos={todos} onUpdate={onUpdate} onDelete={onDelete} /> <List />
 
똑같이 useContext 훅을 불러오고 props값을 비우자.
 
notion image
 
List컴포넌트에서 필요한 값은 todos이다.
구조분해할당으로 todos값만 context로 들고오자.
 
const { todos } = useContext(TodoContext);
 

3. TodoItem 컴포넌트

 
TodoItem도 같은 방법으로 수정해보자.
 
// <TodoItem key={todo.id} {...todo} onUpdate={onUpdate} onDelete={onDelete} />; <TodoItem key={todo.id} {...todo} />;
 
notion image
 
const { onUpdate, onDelete } = useContext(TodoContext);
 
여기까지 모두 완료되면 이전처럼 앱의 기능이 모두
정상적으로 돌아가며 props drliing 현상까지 개선할 수 있다.
 
하지만 문제점이 하나 발생하는데 이전에 했던
최적화 작업이 풀려 하나의 TodoItem을 수정해도
나머지 모든 TodoItem이 같이 리렌더링 된다는 것이다.
 
notion image
 
이 현상은 다음 글에서 같이 개선해보도록 하자.
 
Share article

clubnerdy