오늘 React Context를 톺아보려는 이유는 많은 기업에서 React를 사용하면서 Props 전달이 필요한 상황에서 Context를 적극 활용하고 있다는 생각이 들어서입니다.
이 글에서는 공식 문서(React v18.3.1)를 참고해 Context의 개념과 사용법을 정리해 보려고 합니다.
https://ko.react.dev/learn/passing-data-deeply-with-context
Context를 사용해 데이터를 깊게 전달하기 – React
The library for web and native user interfaces
ko.react.dev
React Context는 왜 등장했을까요?
React를 사용해 본 사람이라면 부모 컴포넌트에서 자식 컴포넌트로 Props를 전달하는 과정을 경험해 보셨을 겁니다.
부모와 자식 컴포넌트 간에 직접 Props를 전달하는 경우에는 큰 문제가 없지만, 중간에 여러 자식 컴포넌트를 거쳐 Props를 계속 전달해야 한다면 과정이 점점 번거로워집니다.
특히 TypeScript를 사용하고 있다면, 각 자식 컴포넌트에서 Props의 타입까지 매번 선언해줘야 해 더욱 귀찮아질 수 있습니다.
이런 문제를 해결하기 위해, React는 Props를 일일이 전달하는 대신 원하는 컴포넌트에 "순간이동" 시키듯 값을 제공할 수 있는 Context를 도입했습니다
Prop drilling

codesandbox 링크로 접속하시면 지금은 각각의 <Heading> 컴포넌트에 level prop을 전달하고 있고 다음과 같이 코드를 수정하려고 합니다.

import Heading from './Heading.js';
import Section from './Section.js';
export default function Page() {
return (
<Section level={1}>
<Heading>Title</Heading>
<Section level={2}>
<Heading>Heading</Heading>
<Heading>Heading</Heading>
<Heading>Heading</Heading>
<Section level={3}>
<Heading>Sub-heading</Heading>
<Heading>Sub-heading</Heading>
<Heading>Sub-heading</Heading>
<Section level={4}>
<Heading>Sub-sub-heading</Heading>
<Heading>Sub-sub-heading</Heading>
<Heading>Sub-sub-heading</Heading>
</Section>
</Section>
</Section>
</Section>
);
}
1단계: Context 생성하기
먼저 context를 만들어야 합니다. 컴포넌트에서 사용할 수 있도록 파일에서 내보내야 합니다.
import { createContext } from 'react';
export const LevelContext = createContext(1);
2단계: Context 사용하기
React에서 useContext Hook과 생성한 Context를 가져옵니다.
levelprop을 제거하고 대신 위에서 가져온 context인 LevelContext에서 값을 읽도록 합니다.
import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';
export default function Heading({ children }) {
const level = useContext(LevelContext);
// ...
}
3단계: Context 제공하기
LevelContext를 자식들에게 제공하기 위해 context provider로 감싸줍니다.
import { LevelContext } from './LevelContext.js';
export default function Section({ level, children }) {
return (
<section className="section">
<LevelContext.Provider value={level}>
{children}
</LevelContext.Provider>
</section>
);
}
다시 한번 정리해 보면 아래의 단계를 거쳤습니다.
- LevelContext라는 이름으로 createContext 훅을 활용해 기본값을 1로 설정하여 Context를 생성합니다.
- Section 컴포넌트에서 LevelContext.Provider로 하위 컴포넌트를 감싸고, value에 level 값을 전달합니다.
- Heading 컴포넌트에서는 기존에 Props로 전달받던 level을 제거하고, 대신 useContext(LevelContext) 훅을 사용해 level 값을 받아와 필요한 분기 처리를 수행하도록 변경합니다.
구현 코드입니다.
https://codesandbox.io/p/sandbox/hl9ysq
https://codesandbox.io/p/sandbox/hl9ysq
codesandbox.io
나의 생각
오늘은 Props를 ‘순간이동’할 수 있는 React의 Context에 대해 살펴보았습니다. 개인적인 컨벤션으로는 컴포넌트 깊이가 3단계를 초과하지 않는 한 Props를 직접 전달하는 방식을 선호하고 있으며, 3단계를 넘어가면 주로 Redux Toolkit이나 Zustand와 같은 전역 상태 관리 라이브러리를 사용해 문제를 해결해 왔습니다.
현재 사내에서는 Context 사용 빈도가 매우 낮지만, 다른 기업에서도 각 사의 컨벤션에 맞추는 것이 중요하다고 생각합니다. 만약 기존 코드에서 Context로 Props를 전달하고 있다면 그 방식을 따르는 것이 맞고, 전역 상태 관리 라이브러리를 사용하고 있다면 이에 맞추어야 한다고 생각합니다. 이처럼 저는 상황에 맞게 적응하며 사용하는 것이 중요하다고 느끼며, 어떤 환경에서도 쉽게 적응할 수 있도록 Context를 포함한 다양한 방식을 공부하고 있습니다.
'지식 정리 📝' 카테고리의 다른 글
Tanstack Query와 Optimistic Update로 Autowini 좋아요 기능 구현하기 (2) | 2024.12.22 |
---|---|
브라우저 언어와 크로스 브라우징 (0) | 2024.10.17 |
S3와 CloudFront로 정적 사이트 호스팅: React 앱 배포 경험 (1) | 2024.10.08 |
WiniLogis 블로그의 가독성 문제 해결 React-Quill을 활용한 텍스트 에디터 적용 (0) | 2024.09.25 |
자바스크립트의 이벤트 루프(Event Loop)란? (1) | 2024.09.07 |