Context API란?
1. Context API란?
Context API는 리액트에서 컴포넌트 트리 전체에 데이터를 전달할 수 있도록 해주는 기능이다. 주로 부모 컴포넌트에서 하위 컴포넌트로 데이터를 전달하는 props의 대안으로 사용된다. Context API를 사용하면 중간에 있는 컴포넌트들을 거치지 않고도 상위에서 하위로 데이터를 전달할 수 있어, 깊은 컴포넌트 트리 구조에서 유용하다.
Context API의 주요 구성 요소
- Context: 데이터를 공유하는 공간을 생성한다.
- Provider: Context의 데이터를 제공하는 컴포넌트로, 하위 컴포넌트들이 Context에 접근할 수 있게 만든다.
- Consumer: Context에 제공된 데이터를 사용하는 컴포넌트이다. (React 16.8부터는
useContext
훅으로 대체 가능하다.)
2. 언제 Context API를 사용하나요?
Context API는 주로 다음과 같은 상황에서 사용된다.
- 전역 상태 관리
- 애플리케이션 내에서 여러 컴포넌트가 동일한 데이터를 필요로 할 때, 예를 들어, 사용자의 로그인 상태나 테마(어두운 모드/밝은 모드) 등의 상태를 여러 컴포넌트에서 공유해야 할 때 유용하다.
- 컴포넌트 간 데이터 전달이 복잡할 때
- 여러 중간 컴포넌트를 거쳐서 데이터를 전달해야 하는 경우가 있다. 이때, props drilling(컴포넌트를 거쳐서 props를 전달하는 방식)이 불편하고 코드가 복잡해지기 때문에, Context API를 사용하여 데이터를 한 번에 전달할 수 있다.
- 상태가 자주 변경되거나 여러 곳에서 사용되는 경우
- 앱 전체에서 여러 컴포넌트들이 동일한 상태에 의존하고 그 상태가 자주 바뀐다면, 상태를 Context API로 관리하면 더 효율적이다.
- 예를 들어, 사용자 언어 설정, 테마 설정, 인증 상태 등.
Context API 사용을 피해야 할 경우
- 많은 데이터를 다루지 않거나 간단한 상태 관리일 경우: 상태가 한정적이고 변경이 적은 경우, 굳이 Context API를 사용할 필요는 없다.
useState
와props
만으로도 충분할 수 있다. - 성능 이슈: Context는 값이 변경될 때마다 해당 값을 사용하는 모든 컴포넌트를 리렌더링하기 때문에, 성능 최적화가 필요할 수 있다. 이를 해결하기 위해
React.memo
,useMemo
등을 사용할 수 있다.
Context API 사용 방법
Context API를 사용하기 위한 단계는 크게 세 가지로 나눌 수 있다.
createContext
로 전역 상태 만들기Provider
로 전역 상태 연결useContext
로 전역 상태 가져오기
1. createContext
로 전역 상태 만들기
createContext
를 사용하여 데이터를 공유할 Context를 생성한다. 이를 통해 여러 컴포넌트 간에 상태를 공유할 수 있게 된다.
import React, { createContext } from 'react';
// Context 생성: 이 Context는 전역 상태를 저장하는 역할을 한다.
const ThemeContext = createContext();
2. Provider
로 전역 상태 연결
Provider
는 Context에 데이터를 공급하는 역할을 한다. Provider
는 그 내부에서 값을 설정하고, 하위 컴포넌트들에 그 값을 전달할 수 있게 해준다.
themeContext.jsx
import React, { useState } from 'react';
import { ThemeContext } from './ThemeContext'; // ThemeContext를 import
// ThemeProvider 컴포넌트: ThemeContext.Provider로 앱의 전역 상태를 관리한다.
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light'); // 기본 테마는 light
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
export default ThemeProvider;
위 코드에서 ThemeContext.Provider
는 theme
와 toggleTheme
함수를 전역 상태로 제공하며, 이를 value
로 설정한다. children
은 Provider
안에 감싸진 컴포넌트들이며, 이들 컴포넌트는 모두 ThemeContext
를 통해 전역 상태에 접근할 수 있다.
App.js
import React from 'react';
import { ThemeProvider } from './ThemeContext'; // ThemeProvider import
import ThemeToggler from './ThemeToggler'; // ThemeToggler import
const App = () => {
return (
<ThemeProvider>
<ThemeToggler />
</ThemeProvider>
);
};
export default App;
App
을 ThemeProvider
로 감싸서 ThemeContext
에서 제공한 데이터를 사용할 수 있다.
3. useContext
로 전역 상태 가져오기
useContext
훅을 사용하여 Context에 제공된 데이터를 컴포넌트에서 쉽게 가져올 수 있다.
ThemeToggler.jsx
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext'; // ThemeContext를 import
// 테마를 변경하는 버튼을 가진 컴포넌트
const ThemeToggler = () => {
const { theme, toggleTheme } = useContext(ThemeContext); // useContext로 전역 상태 가져오기
return (
<div>
<h1>현재 테마: {theme}</h1>
<button onClick={toggleTheme}>테마 변경</button>
</div>
);
};
export default ThemeToggler;
위 코드에서는 useContext(ThemeContext)
를 통해 theme
와 toggleTheme
을 가져온다. 이 컴포넌트는 현재 테마를 표시하고, 버튼 클릭 시 테마를 전환하는 기능을 수행한다.
작동 원리
ThemeProvider
는 전역 상태인theme
와toggleTheme
를 제공한다.ThemeToggler
는useContext
훅을 사용하여 이 상태를 가져와서 테마를 화면에 표시하고, 버튼 클릭 시 테마를 변경한다.App
은ThemeProvider
로 감싸져 있어,ThemeToggler
가ThemeContext
에서 제공한 데이터를 사용할 수 있다.
Context를 사용하기 전에 고려할 것
Context는 남용하기 쉽기 때문에 신중하게 사용해야 한다. 여러 레벨 깊이로 props를 전달해야 한다고 해서 무작정 정보를 context에 넣는 것이 좋은 선택이 아닐 수 있다.
- 먼저 Props 전달하기
컴포넌트들 간에 여러 개의 props를 전달하는 것이 불편할 수 있지만, 이는 데이터를 사용하는 컴포넌트가 어떤 데이터를 사용하는지 명확히 해주는 좋은 방법이다. 이를 통해 데이터 흐름이 props를 통해 분명해지며, 코드의 유지보수와 관리가 용이해진다. - 컴포넌트 추출 후 JSX를 children으로 전달하기
데이터를 사용하지 않는 중간 컴포넌트 층을 지나야 하는 경우, 데이터가 전달되는 중간 컴포넌트들에 대해 고민할 수 있다. 이때 데이터를 사용하지 않는 컴포넌트를 추출하고, children prop으로 전달하는 방법이 유효하다. 이렇게 하면 데이터가 필요한 컴포넌트와 데이터를 전달하는 컴포넌트 사이의 중간층을 줄여 더욱 간결한 구조로 만들 수 있다. - Context 사용 여부 결정하기
만약 위의 방법들이 잘 맞지 않거나, 중간에 지나치게 많은 props 전달이 필요하거나 복잡한 구조가 된다면, 그때 context를 고려해볼 수 있다. 단, context는 자주 변경되는 값이나, 여러 컴포넌트 간에 공유되어야 하는 값들을 다룰 때 유용하다.
Context 사용예시
- 테마 지정하기
다크 모드와 같은 시각적 요소를 사용자에게 제공하는 애플리케이션에서는, context provider를 앱의 최상단에 두고 필요한 컴포넌트에서 해당 값을 가져와 사용할 수 있다. 이를 통해 테마 설정을 앱 전체에서 손쉽게 관리할 수 있다. - 현재 계정 관리
로그인한 사용자의 정보는 많은 컴포넌트에서 필요할 수 있다. 이때, context에 현재 계정을 저장해두면, 컴포넌트 트리 어디에서나 해당 정보를 쉽게 가져올 수 있다. 예를 들어, 댓글 작성 시 다른 사용자로 댓글을 달고 싶을 때, 각 컴포넌트가 같은 사용자 정보를 가져올 수 있게 된다. 이와 같은 상황에서는 여러 계정을 관리할 수 있는 구조가 유용하다. - 라우팅 관리
대부분의 라우팅 솔루션은 내부적으로 현재 경로를 추적하기 위해 context를 사용한다. 이 방식을 사용하면 애플리케이션 내의 링크나 버튼들이 현재 경로에 따라 활성화 여부를 판단할 수 있다. - 상태 관리
애플리케이션이 커지면서 여러 컴포넌트가 동일한 상태를 필요로 할 때, 상태 관리가 복잡해질 수 있다. 이때, 상태를 context와 함께 관리하면, 멀리 떨어져 있는 컴포넌트들 간에 상태를 손쉽게 공유하고 변경할 수 있다. 예를 들어, reducer와 context를 결합하여 복잡한 상태를 효율적으로 관리할 수 있다.
'Frontend > React' 카테고리의 다른 글
[React] 전역 상태관리1(Prop Drilling, 전역상태 관리의 필요성) (0) | 2025.04.18 |
---|---|
[React] 클래스, 함수형 컴포넌트 생명주기(Lifecycle)와 생명주기 함수(Hook) (1) | 2025.04.10 |
React가 SPA를 구현하는 방법 (0) | 2025.04.07 |
SPA vs MPA (0) | 2025.04.07 |
[면접공부] 리액트에서 index를 key값으로 사용하면 안되는 이유 (0) | 2025.01.09 |