React를 사용하다 보면 컴포넌트 간에 데이터를 주고받는 일이 자주 발생한다.
처음에는 props로 간단하게 전달하면 되지만,
구조가 깊어질수록 props를 여러 단계를 거쳐 전달해야 하는 상황이 생긴다.
이를 props drilling이라고 부른다고 했었다. (https://frontlogdev.tistory.com/34)
전역 상태를 관리하는 방법 중 하나가 바로 Context API다.
이 글에서는 Context API가 무엇인지, 언제 사용하는지,
그리고 어떻게 적용하는지 차근차근 예제를 통해 정리해보았다.
🧠 전역 상태(Global State)란?
하나의 컴포넌트에만 쓰는 로컬 상태가 아니라, 앱 전체에서 공유되는 상태를 말한다.
예: 로그인 여부, 사용자 정보, 다크모드 설정 등.
🧩 Context API란?
Context API는 React에서 컴포넌트 트리 전체에 데이터를 전역으로 공급할 수 있는 기능이다.
일반적으로는 상위 컴포넌트에서 하위 컴포넌트로 props를 통해 데이터를 전달하지만,
이 방식은 컴포넌트가 많아질수록 코드가 복잡해지고 관리가 어려워진다.
Context API를 사용하면 상태를 중앙에서 관리하고, 필요한 곳에서 직접 꺼내 쓸 수 있다.
🧭 언제 Context API를 사용하나요?
다음과 같은 상황에서 Context를 사용하면 유용하다.
- ✅ 여러 컴포넌트에서 동일한 데이터를 공유해야 할 때 (예: 로그인 상태, 사용자 정보, 다크모드 설정 등)
- ✅ props를 너무 많이 전달해야 해서 코드가 복잡할 때 (props drilling 문제 해결)
- ✅ 간단한 전역 상태 관리를 하고 싶은데 Redux 같은 무거운 도구는 쓰기 싫을 때
💡 단, Context에 너무 많은 상태를 몰아넣는 것은 성능 저하를 일으킬 수 있으므로, 꼭 필요한 데이터만 관리하는 것이 좋다.
🚀 전역 상태 관리의 장점
Context API를 이용한 전역 상태 관리에는 다음과 같은 장점이 있다.
- ✅ 상태 공유가 간편함: 여러 컴포넌트에서 props 없이 상태를 쉽게 꺼내 쓸 수 있다.
- ✅ 코드가 깔끔해짐: 상태 전달에 필요한 코드가 줄어들어 컴포넌트 구조가 단순해진다.
- ✅ 유지보수가 쉬움: 상태 로직이 한 곳에 집중되어 있어 디버깅이나 기능 수정이 편하다.
🛠️ Context API 사용법
전역 상태를 만들고 사용하는 과정은 아래 3단계로 구성된다.
1️⃣ createContext로 틀 만들기
import { createContext } from "react";
const counterContext = createContext();
createContext()는 전역 상태를 정의할 기본 틀을 만드는 함수다.
2️⃣ Provider로 전역 상태 전달하기
import { useState } from "react";
export function CounterProvider({ children }) {
const [counter, setCounter] = useState(0);
return (
<counterContext.Provider value={{ counter, setCounter }}>
{children}
</counterContext.Provider>
);
}
CounterProvider는 상태값과 그 상태를 바꾸는 함수를 context로 내려보낸다.
이 컴포넌트로 App을 감싸면, 내부 모든 컴포넌트에서 counter와 setCounter를 사용할 수 있다.
3️⃣ useContext로 전역 상태 꺼내 쓰기
import { useContext } from "react";
export function useCounter() {
return useContext(counterContext);
}
커스텀 훅을 만들어 두면 코드가 더 깔끔하고 재사용하기도 쉽다.
💻 6. 실제 사용 예제
이제 카운터 예제를 통해 Context API를 실제로 어떻게 사용하는지 단계별로 확인해보자.
📄 main.jsx – App을 전역 상태로 감싸기
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import { CounterProvider } from "./context/counterContext";
ReactDOM.createRoot(document.getElementById("root")).render(
<CounterProvider>
<App />
</CounterProvider>
);
🔍 설명
CounterProvider는 App을 감싸 전역 상태를 공급한다.
이렇게 설정해 두면 App과 그 하위 컴포넌트들은 모두 counterContext에 접근할 수 있다.
📄 App.jsx – 전역 상태 꺼내 쓰기
import { useCounter } from './context/counterContext';
function App() {
const { counter, setCounter } = useCounter();
return (
<>
<div>Counter: {counter}</div>
<button onClick={() => setCounter(prev => prev + 1)}>+1</button>
<button onClick={() => setCounter(prev => prev - 1)}>-1</button>
</>
);
}
🔍 설명
useCounter()를 호출하면 현재 counter 값과 그것을 수정하는 setCounter 함수를 사용할 수 있다.
이 값들은 모두 CounterProvider에서 전달받은 것이다.
📄 자식 컴포넌트에서도 사용하기
function Child3() {
const { counter } = useCounter();
return <div>Child3 : {counter}</div>;
}
function Child6() {
const { setCounter } = useCounter();
return (
<button onClick={() => setCounter(prev => prev + 1)}>Child6 +</button>
);
}
🔍 설명
Child3와 Child6은 App의 하위 컴포넌트라고 가정한다.
별도로 props를 전달받지 않았지만, useCounter()만으로 전역 상태를 자유롭게 사용할 수 있다.
이처럼 깊은 위치의 컴포넌트에서도 상태를 직접 접근할 수 있는 것이 Context API의 가장 큰 장점이다.
✅ 마무리
- Context API는 props 없이 전역 상태를 관리할 수 있는 기능이다.
- 작은 규모의 프로젝트나 간단한 상태 관리에 적합하다. (예: 로그인 정보, 테마, 카운터 등)
- 전역 상태를 만들고, 필요한 컴포넌트에서 useContext로 쉽게 꺼내 쓸 수 있다.
- 복잡한 props 구조를 간단하게 바꿔주고 유지보수성을 높여준다.
- Redux, Zustand, Recoil 등 외부 상태 관리 도구도 있지만,
대부분의 요구는 Context API만으로도 충분히 해결 가능하다.
'코딩이야기𖦹 > React' 카테고리의 다른 글
| 📌 React 렌더링 최적화: memo, useMemo, useCallback 완전정복하기 (0) | 2025.04.23 |
|---|---|
| 📌 복잡한 상태관리를 깔끔하게! Redux 개념 정리 (0) | 2025.04.22 |
| 📌 React 앱을 가볍게! 전역 상태 관리로 구조 최적화하기 (0) | 2025.04.18 |
| 📌 Tailwind CSS 진짜 편한가? (0) | 2025.04.17 |
| 📌 styled-components 정리! (2) | 2025.04.16 |