Context가 무엇인지 알아보고, Context로 [할 일 관리] 앱을 리팩토링하자.
Context
Context란 리액트 컴포넌트 트리 전체에 데이터를 공급하는 기능으로, Context를 통해 Props Drilling 문제를 해결할 수 있다. 이때 Context가 데이터를 공급하는 범위를 '같은 문맥'이라고 표현하기도 하는데, 이 문맥이라느 글의 방향을 말한다.
Props Drilling
Props Drilling이란 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때, 중간에 위치한 모든 컴포넌트에 일일히 Props를 전달해야 하는 문제를 말한다. 리액트의 트리 상에서 2단계 이상 떨어져 있는 컴포넌트에는 직접 데이터를 전달할 수 없기 때문이다.
이런 문제가 발생하면 코드가 복잡해지고 유지보수에 어려움이 생긴다. 따라서 Context를 사용하면, 단계마다 하나하나 Props를 사용하지 전달하지 않고도 컴포넌트 트리 전역에 데이터를 공급할 수 있어 해당 문제가 해결된다.
Props 사용의 장단점
일반적인 Props를 사용했을 때의 장점은 다음과 같다.
- Props는 리액트 컴포넌트가 기본적으로 제공하는 데이터 전달 방법이기 때문에 별도의 설정이 필요하지 않다.
- 데이터의 전달이 부모-자식으로 명시적이기 때문에 데이터의 흐름을 쉽게 추적할 수 있다.
하지만 앞서 말했듯 Props Drilling 문제가 발생하고, Props를 전달하는 컴포넌트가 많아지면 데이터 전달 구조를 파악하고 유지보수하는 것이 어려워진다.
Context 사용의 장단점
이때 Context를 사용한다면 생기는 장점은 다음과 같다.
- 중간 컴포넌트를 거치지 않고도 데이터를 여러 컴포넌트에 전달할 수 있어 Props Drilling 문제를 해결할 수 있다.
- App의 여러 컴포넌트에서 공통적으로 사용되는 데이터를 중앙에서 관리하고 공급할 수 있다.
- 데이터의 공급과 소비를 명확하게 분리할 수 있어 코드가 깔끔해지고 유지보수가 용이하다.
하지만 Context를 설정하고 사용하는 것에 추가적인 코드 입력 및 구조 설계가 필요하고, 작은 프로젝트에서는 오히려 불필요한 복잡성을 초래하게 될 수도 있다. 또한 Context로 데이터를 공급받는 컴포넌트는 데이터의 흐름이 명확하지 않기에 디버깅이 어려워지는 문제가 생길 수 있다.
ContextAPI
Context를 만들고 사용하는 리액트 기능으로, createContext, ContextProvider 등이 있다.
Context 구조 분리하기
리팩토링
리팩토링이란 사용자에게 제공하는 기능은 변경하지 않되 내부 구조를 개선하는 작업이다.
**코드 작성 문제**
const TodoContext = ____________();
return (
<TodoContext.______ value={{ todos, addTodo, toggleTodo, deleteTodo }}>
{________}
</TodoContext.______>
);
2. MemoContext.Provider를 생성하고 MemoEditor에 전체 메모의 개수(memo.length), 중요표시한 메모의 개수(importantMemos), 완료된 메모의 개수(finishedMemos) Context를 생성하는 코드를 작성해 보자.
콘텍스트
O
프롭스 드릴링
리팩토링
X, 컴포넌트 밖에서만 생성 가능
useContext
리렌더링
const TodoContext = createContext();
return (
<TodoContext.Provider value={{ todos, addTodo, toggleTodo, deleteTodo }}>
{children}
</TodoContext.Provider>
);
return (
<MemoContext.Provider>
<div className="App">
<MemoEditor onCreate={onCreate} />
<div>전체 메모 개수 : {memo.length}</div>
<div>중요표시한 메모의 개수 : {importantMemo}</div>
<div>완료된 메모의 개수 : {finishedMemo}</div>
</div>
</MemoContext.Provider>
);
출처: 이정환, 『한 입 크기로 잘라먹는 리액트』, 프로그래밍인사이트(2023),
https://reactjs.winterlood.com/.
Corner React.js 2
Editor: Borybop
[React.js 2팀] 7장. useReducer와 상태 관리 ~ 8장. 최적화 (0) | 2025.01.10 |
---|---|
[React.js 2팀] project 2 [할 일 관리] 앱 만들기 2 (Read: 할 일 리스트 렌더링하기 ~ Delete: 할 일 삭제하기) (1) | 2025.01.03 |
[React.js 2팀] project 2 [할 일 관리] 앱 만들기 1 (프로젝트 준비하기 ~ Create: 할 일 추가하기) (1) | 2024.12.27 |
[React.js 2팀] 8장. Hooks (0) | 2024.11.29 |
[React.js 2팀] project 1 [카운터] 앱 만들기 ~ 6장. 라이프 사이클과 리액트 개발자 도구 (0) | 2024.11.22 |