개발천재

[ReactJS] 데이터 공유를 위한 useContext 알아보기 본문

개발 준비/ReactJS

[ReactJS] 데이터 공유를 위한 useContext 알아보기

세리블리 2025. 4. 4. 08:44
반응형

useContext 이해하기

useContext는 React의 훅 중 하나로, Context API를 사용하여 컴포넌트 트리에서 값을 쉽게 전달할 수 있도록 도와준다. 일반적으로 부모 컴포넌트에서 Context를 Provider를 사용해 값을 전달하고, 하위 컴포넌트에서는 useContext로 이 값을 쉽게 가져올 수 있다. 주로 전역적인 상태(예: 테마, 로그인 상태 등)를 관리할 때 유용하다.

 

Context는 컴포넌트 트리 전체에서 전역적으로 데이터를 공유할 수 있게 해준다. 하지만 사용은 신중하게 해야 한다. 너무 많은 데이터를 Context로 전달하면 성능 저하가 발생할 수 있기 때문이다.

useContext는 값이 변경되면 해당 컴포넌트를 리렌더링한다. 이는 리액트의 기본 동작처럼 상태 값이 변경될 때마다 컴포넌트가 다시 렌더링되는 것과 유사하다.

useContext는 클래스형 컴포넌트에서 사용할 수 없다. 클래스형 컴포넌트에서는 Context.Consumer를 사용해야 한다.

 

useContext 사용법

1. Context 생성: React.createContext()를 사용하여 Context를 생성합니다.
2. Context Provider로 값 전달: Context.Provider를 사용하여 하위 컴포넌트들에 값을 제공합니다.
3. useContext로 값 사용: useContext를 사용하여 하위 컴포넌트에서 값을 쉽게 읽어옵니다.

 


 

Context API

React의 Context API는 리액트에서 자체적으로 제공하는 API로, 애플리케이션 내에서 데이터를 전역적으로 관리하고 컴포넌트 트리 간에 데이터를 쉽게 공유할 수 있게 해준다. 전역적으로 관리한다는 것은 중앙에서 데이터를 관리하고 필요할 때 그 데이터를 각 컴포넌트가 쉽게 가져가 사용할 수 있도록 하는 방식을 말한다. 예를 들어, 여러 컴포넌트에서 동일한 데이터를 사용해야 할 때, props를 통해 일일이 전달할 필요 없이 Context를 사용하면 더 효율적으로 데이터를 전달할 수 있다.

 

 

기본 예시
MyContext.Provider는 value 값을 하위 컴포넌트들에 제공한다.
Child 컴포넌트는 useContext(MyContext)를 사용해 MyContext에서 제공된 값을 읽어온다.
Child 컴포넌트는 value 값을 h1 태그로 렌더링한다.

Context 생성

import React, { createContext, useState } from 'react';

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


Provider로 값 전달

function App() {
  const [value, setValue] = useState('Hello, Context!');

  return (
    <MyContext.Provider value={value}>
      <Child />
    </MyContext.Provider>
  );
}

 

 

useContext로 값 사용

import React, { useContext } from 'react';

function Child() {
  // useContext로 Context 값 읽어오기
  const value = useContext(MyContext);

  return <h1>{value}</h1>;
}

 

 


 

 

useContext의 유용한 사용 사례

1. 테마 관리 (다크 모드/라이트 모드)

애플리케이션에서 다크 모드와 라이트 모드를 전환할 수 있는 기능을 제공할 때 유용하다. 사용자 경험을 개선하고, 다양한 디자인을 쉽게 구현할 수 있다.

테마를 전역 상태로 관리하고, 컴포넌트에서 이를 받아와 스타일을 적용한다.

import React, { createContext, useState, useContext } from 'react';

// 1. Context 생성
const ThemeContext = createContext();

function App() {
  const [isDarkMode, setIsDarkMode] = useState(false); // 다크모드 상태 관리

  // 2. Provider로 상태 전달
  return (
    <ThemeContext.Provider value={{ isDarkMode, setIsDarkMode }}>
      <div className={isDarkMode ? 'dark' : 'light'}>
        <Header />
        <Main />
      </div>
    </ThemeContext.Provider>
  );
}

function Header() {
  const { isDarkMode, setIsDarkMode } = useContext(ThemeContext); // 3. useContext로 상태 가져오기

  return (
    <header>
      <h1>Current Theme: {isDarkMode ? 'Dark Mode' : 'Light Mode'}</h1>
      <button onClick={() => setIsDarkMode(!isDarkMode)}>
        Toggle Theme
      </button>
    </header>
  );
}

function Main() {
  const { isDarkMode } = useContext(ThemeContext); // 3. useContext로 상태 가져오기

  return <main className={isDarkMode ? 'dark' : 'light'}>Main content</main>;
}

export default App;

 

 

2. 사용자 인증 상태 (로그인 여부)
애플리케이션에서 사용자의 로그인 상태를 여러 컴포넌트에서 참조할 필요가 있을 때 유용하다. 예를 들어, 로그인한 사용자의 정보를 전역에서 관리하고 이를 각 컴포넌트에서 쉽게 사용할 수 있다.

로그인 상태를 useContext로 관리하여 로그인한 사용자에게 맞는 UI를 제공할 수 있다.

const AuthContext = createContext();

function App() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  return (
    <AuthContext.Provider value={{ isAuthenticated, setIsAuthenticated }}>
      <Navbar />
      <Main />
    </AuthContext.Provider>
  );
}



3. 다국어 지원 (언어 설정)
다국어 지원이 필요한 애플리케이션에서 언어 설정을 관리할 때 유용하다. 사용자가 선택한 언어를 전역적으로 관리하고, 각 컴포넌트에서 이를 읽어와 다국어 콘텐츠를 렌더링할 수 있다.

애플리케이션에서 지원하는 여러 언어를 전역 상태로 관리하고, useContext를 사용하여 해당 언어에 맞는 텍스트를 보여준다.

const LanguageContext = createContext();

function App() {
  const [language, setLanguage] = useState('en');
  return (
    <LanguageContext.Provider value={{ language, setLanguage }}>
      <Header />
      <Content />
    </LanguageContext.Provider>
  );
}

 

 

4. 애플리케이션 상태 관리 (글로벌 상태)
애플리케이션 내에서 전역적으로 관리해야 하는 상태가 있을 때, 예를 들어 테이블 데이터, 쇼핑카트 아이템, 알림 등의 상태를 전역에서 공유해야 할 때 유용하다.

쇼핑몰 애플리케이션에서 useContext를 사용하여 장바구니에 담긴 상품 데이터를 전역적으로 관리할 수 있다.

const CartContext = createContext();

function App() {
  const [cartItems, setCartItems] = useState([]);

  return (
    <CartContext.Provider value={{ cartItems, setCartItems }}>
      <Navbar />
      <ProductList />
    </CartContext.Provider>
  );
}

 

 

5. 모달 상태 관리
여러 컴포넌트에서 모달의 열림/닫힘 상태를 제어하고, 이를 전역적으로 관리할 때 유용하다. 예를 들어, 여러 곳에서 모달을 띄워야 하는 경우 useContext를 사용하면 모달 상태를 쉽게 관리할 수 있다.

애플리케이션 내에서 여러 컴포넌트가 모달을 띄울 수 있게 하고, 모달 상태를 useContext로 관리한다.

const ModalContext = createContext();

function App() {
  const [isModalOpen, setIsModalOpen] = useState(false);

  return (
    <ModalContext.Provider value={{ isModalOpen, setIsModalOpen }}>
      <Header />
      <Modal />
    </ModalContext.Provider>
  );
}

 

 

6. 애플리케이션의 전역 로딩 상태 관리
애플리케이션에서 비동기 작업이 진행되는 동안 전역적으로 로딩 상태를 관리하고, 모든 컴포넌트에서 로딩 상태를 쉽게 사용할 수 있게 할 때 유용하다. 예를 들어, 데이터 로딩 시 스피너나 로딩 메시지를 표시할 수 있다.

데이터를 불러오는 동안 로딩 상태를 전역에서 관리하고, 이를 모든 컴포넌트에서 쉽게 참조하여 로딩 UI를 표시한다.

const LoadingContext = createContext();

function App() {
  const [isLoading, setIsLoading] = useState(false);

  return (
    <LoadingContext.Provider value={{ isLoading, setIsLoading }}>
      <Header />
      <Content />
    </LoadingContext.Provider>
  );
}

 

 

7. 폼 상태 관리
복잡한 폼이 여러 단계에 걸쳐서 이루어지는 경우, useContext를 사용하여 폼 데이터를 전역적으로 관리할 수 있다. 예를 들어, 여러 단계로 이루어진 회원 가입 폼에서 각 단계의 상태를 쉽게 관리할 수 있다.

폼의 각 필드 데이터를 useContext로 관리하여, 다른 컴포넌트에서 이 데이터를 읽고 업데이트할 수 있게 한다.

const FormContext = createContext();

function App() {
  const [formData, setFormData] = useState({ name: '', email: '' });

  return (
    <FormContext.Provider value={{ formData, setFormData }}>
      <FormStep1 />
      <FormStep2 />
    </FormContext.Provider>
  );
}

 

 

8. 권한 및 역할 관리
사용자의 권한이나 역할에 따라 접근할 수 있는 UI를 다르게 보여줘야 할 때 유용하다. 예를 들어, 관리자와 일반 사용자에게 다른 UI를 제공할 수 있다.

사용자의 역할을 useContext를 통해 관리하고, 각 컴포넌트에서 해당 역할에 맞는 UI를 렌더링한다.

const UserContext = createContext();

function App() {
  const [role, setRole] = useState('user');

  return (
    <UserContext.Provider value={{ role, setRole }}>
      <Navbar />
      <AdminPanel />
    </UserContext.Provider>
  );
}

 

 

useContext 예시 (더 복잡한 경우)

import React, { createContext, useState, useContext } from 'react';

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

function App() {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Header />
      <Main />
    </ThemeContext.Provider>
  );
}

function Header() {
  const { theme, setTheme } = useContext(ThemeContext);

  return (
    <div>
      <h1>Current Theme: {theme}</h1>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle Theme
      </button>
    </div>
  );
}

function Main() {
  const { theme } = useContext(ThemeContext);

  return <div className={theme}>Main content</div>;
}

 

반응형