리액트 훅 | useContext에 대해 알아보기

2025. 8. 18. 17:17·FRONTEND/React

React에서 useContext는 전역적으로 값을 공유할 수 있게 해주는 중요한 도구입니다.

본격적으로 useContext를 살펴보기 전에 React의 기본 개념부터 차근차근 알아보겠습니다.

 

0. React 기본 개념

(1) 컴포넌트

React 앱은 전부 컴포넌트로 구성됩니다.

컴포넌트는 재사용 가능한 UI 조각으로 버튼, 헤더, 카드, 페이지 전체 등 다양한 크기로 만들 수 있습니다.

function Button() {
  return <button>버튼</button>;
}

 

(2) Props 

Props는 컴포넌트에 값을 전달하는 방식입니다.

부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때 사용하며, HTML 태그의 속성과 유사합니다.

function Hello({ name }) {
  return <h1>안녕, {name}!</h1>;
}

<Hello name="유저" />   // "안녕, 유저!"

 

(3) State

State는 컴포넌트 내부에서 변하는 값을 관리하는 메커니즘입니다.

useState 훅으로 선언하고, 값이 바뀌면 해당 컴포넌트가 재렌더링됩니다.

function Counter() {
  const [count, setCount] = useState(0);  // 초기값 0
  return (
    <div>
      <p>현재: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

 

(4) Props Drilling 문제

값이 깊은 자식 컴포넌트에서만 필요할 때 문제가 발생합니다.

<App>
  <Layout user={user}>
    <Sidebar user={user}>
      <Profile user={user} />  // 실제로 여기서만 user가 필요
    </Sidebar>
  </Layout>
</App>

이처럼 중간 단계의 컴포넌트들이 불필요하게 user를 전달해야 하는 상황을 Prop Drilling이라고 합니다.

코드가 지저분해지고 유지보수가 어려워지는 단점이 있습니다.

 

(5) Context란

Context는 상태관리 도구가 아니라 값을 전달하는 통로입니다.

마치 라디오 방송과 같은 개념으로 이해할 수 있습니다.

Provider : 데이터 송출 (Like 방송국)

useContext : 어디서든 수신 (Like 라디오)

// Context 생성
const UserContext = createContext();

// Provider로 데이터 방송
<UserContext.Provider value={user}>
  <App />  // 이 안의 모든 컴포넌트가 user에 접근 가능
</UserContext.Provider>

 

1. useContext란

usecontext는 Context에서 값을 꺼내는 훅입니다.

쉽게 말해, 전역으로 공유된 값(테마, 유저 정보)을 필요한 컴포넌트에서 바로 꺼내 쓸 수 있게 해 줍니다.

 

Context API의 3가지 핵심 요소

- createContext -> Context 생성

- Provider -> 값 제공

- useContext -> 값 사용

 

2. useContext 사용법

1단계 : Context 생성

import { createContext } from 'react';

const ThemeContext = createContext();
// 또는 기본값 설정
const ThemeContext = createContext('light');

 

2단계 : Provider로 값 제공

function App() {
  const [theme, setTheme] = useState('light');
  
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Header />
      <Main />
    </ThemeContext.Provider>
  );
}

 

3단계 : useContext로 값 사용

 
import { useContext } from 'react';

function Header() {
  const { theme, setTheme } = useContext(ThemeContext);
  
  return (
    <header className={theme === 'dark' ? 'dark-theme' : 'light-theme'}>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        {theme} 모드
      </button>
    </header>
  );

 

3. useContext vs 다른 방법들

(1) Props Drilling vs useContext

// Props Drilling
function App() {
  const [user, setUser] = useState(null);
  return <Layout user={user} setUser={setUser} />;
}

function Layout({ user, setUser }) {
  return <Header user={user} setUser={setUser} />;
}

function Header({ user }) {
  return <div>{user?.name}</div>;
}

// useContext 활용
function Header() {
  const { user } = useAuth();  // 바로 접근 가능
  return <div>{user?.name}</div>;
}

 

(2) localStorage 직접 사용 vs useContext

// localStorage 직접 접근
function Header() {
  const user = JSON.parse(localStorage.getItem('user') || 'null');
  return <div>{user?.name}</div>;
} // 로그아웃 시 → 새로고침해야 반영됨


// useContext 활용
function Header() {
  const { user } = useAuth();
  return <div>{user?.name}</div>;
} // 로그아웃 시 → 모든 UI가 즉시 업데이트됨

Q. 유저 정보를 localStorage에서 바로 가져와서 쓸 수 있지 않나요?

A. localStorage 값이 바뀌어도 React 컴포넌트가 자동으로 리렌더링 되지 않습니다. 따라서 로그아웃 후 헤더의 사용자 이름이 바뀌는 등의 UI 변화가 즉시 일어나지 않아 사용자 경험이 떨어집니다.

 

Q. 그러면 useContext 대신 Zustand, Redux 같은 상태 관리 도구를 사용하면 되지 않나요?

A. 규모에 따라 적절한 도구를 선택하는 것이 중요합니다.

 

- useContext : 간단한 전역 상태에 적합 (테마, 로그인 유저, 언어 설정 등)

- Redux/Zustand : 복잡한 상태 로직, 미들웨어, 디버깅 도구가 필요한 경우에 적합

 

작은 규모 프로젝트에서는 useContext가 더 가볍고 직관적입니다.

 

4. useContext 사용 시 주의사항

(1) 불필요한 리렌더링 최적화

Context 값이 바뀌면 해당 Context를 사용하는 모든 컴포넌트가 리렌더링 됩니다.

// 매번 새로운 객체 생성
function App() {
  const [theme, setTheme] = useState('light');
  
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>  {/* 매 렌더링마다 새 객체 */}
      <Header />
    </ThemeContext.Provider>
  );
}

// useMemo로 최적화
function App() {
  const [theme, setTheme] = useState('light');
  
  const themeValue = useMemo(() => ({ theme, setTheme }), [theme]);
  
  return (
    <ThemeContext.Provider value={themeValue}>
      <Header />
    </ThemeContext.Provider>
  );
}

 

(2) Context 분리하기

하나의 Context에 너무 많은 값을 넣지 말고, 관련된 기능별로 분리하는 것이 좋습니다.

 
// 모든 것을 하나에
const AppContext = createContext();
// value={{ user, theme, language, notifications, ... }}

// 기능별로 분리
const AuthContext = createContext();    // 사용자 인증
const ThemeContext = createContext();   // 테마
const I18nContext = createContext();    // 다국어

 

마무리

useContext는 다음과 같은 상황에서 특히 유용합니다.

  • 로그인된 사용자 정보 관리 : 앱 전반에서 사용자 데이터 접근
  • 테마 설정 : 라이트/다크 모드 전환
  • 다국어(i18n) 설정 : 언어 변경 및 번역 텍스트 관리
  • 앱 전역 환경 설정 : API 엔드포인트, 환경변수 등

언제 useContext를 선택해야 할까요?

작은 규모의 전역 상태 공유라면 useContext가 가장 간단하고 가벼운 해결책입니다.

하지만 더 복잡한 상태 로직, 미들웨어, 강력한 디버깅 도구가 필요하다면 Redux나 Zustand 같은 전문 상태 관리 라이브러리가 더 적합합니다.

React의 내장 기능만으로도 충분히 강력한 전역 상태 관리가 가능하다는 점에서 useContext는 반드시 알아야 할 필수 도구입니다.

'FRONTEND > React' 카테고리의 다른 글

비동기 처리에서의 Race Condition 정리  (1) 2025.12.11
리액트 훅 | useActionState에 대해 알아보기  (3) 2025.08.14
리액트 훅 | useMemo에 대해 알아보기  (6) 2025.08.13
리액트 훅 | useCallback에 대해 알아보기  (8) 2025.08.12
리액트 훅 | useEffect에 대해 알아보기  (5) 2025.08.11
'FRONTEND/React' 카테고리의 다른 글
  • 비동기 처리에서의 Race Condition 정리
  • 리액트 훅 | useActionState에 대해 알아보기
  • 리액트 훅 | useMemo에 대해 알아보기
  • 리액트 훅 | useCallback에 대해 알아보기
uoaheu
uoaheu
uoaheu 님의 블로그 입니다.
  • uoaheu
    uoaheu 님의 블로그
    uoaheu
  • 전체
    오늘
    어제
    • 분류 전체보기 (50)
      • 알고리즘 (7)
      • CS (9)
      • FRONTEND (9)
        • React (12)
        • Kotlin (1)
        • JS (5)
        • HTML (2)
      • SQL (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    useactionstate
    유레카3기
    mysql
    토스 uiux
    백준1926번
    혼자서 공부하는 네트워크
    toss uiux
    이더넷프레임
    BFS
    엘지유플러스유레카프론트엔드
    mysql 피벗테이블
    토스분석
    toss 분석
    리액트usestate
    mysql로 피벗테이블만들기
    멀티캠퍼스it부트캠프
    부트캠프후기
    알고리즘
    boj25418
    토스 앱 분석
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
uoaheu
리액트 훅 | useContext에 대해 알아보기
상단으로

티스토리툴바