Context API란?
내가 작성해 온 지난 포스팅을 보면 그 동안은 props를 통해 상태와 함수를 전달하는 방식을 사용했다. 이러한 방식의 문제점은 계층 중간에 많은 컴포넌트를 거쳐야 하는 경우에는 props를 계속 중복적으로 작성하여 전달하는 것이 번거롭고 불편하다.
그렇다면 부모 컴포넌트가 트리 아래에 있는 모든 컴포넌트에 대해 깊이에 상관없이 전달할 수 있는 방식이 있으면 좋지 않을까 하는 생각을 할 수 있다. 그리고 그것을 가능하게 하는 것이 바로 Context API이다.
Context API와 props 전달 방식의 장단점
1. 명시적 VS 암묵적
- props: 부모 - >자식 컴포넌트에 props를 무조건 작성해주어 태그 레벨에서 명확하게, 명시적으로 어떠한 값을 내려주는지가 보인다.
- context: useContext의 호출 위치를 봐야 비로소 어디서 값이 왔는지 알 수 있다.(아래에서 사용법을 설명하며 useContext도 설명 예정)
2. 컴포넌트의 재사용성
- props: props만 사용하게 되면 그 컴포넌트는 어떤 컨텍스트에도 의존하지 않으니 이식성이 높다.
- context: context에 너무 많이 의존하면 Provider 없이 단독으로 떼어쓰기 어려워질 수 있다. (아래에서 사용법을 설명하며 Provider도 설명 예정)
3. Prop Drilling
- props: 중간 레이어에서 실제로 필요없는 props를 계속 전달해야 하는 상황이 발생할 수 있다.
- context: 불필요한 props 선언없이 자식 컴포넌트 어디서든 바로 꺼내 쓸 수 있다.
Context API 사용법
1. Context 생성
-> AppContext.jsx를 새롭게 만들어 어플리케이션 전역으로 사용되는 상태나 함수를 관리한다.
import React, { createContext } from "react";
export const AppContext = createContext();
-> 위와 같이 createContext()를 통해 context를 생성하고 내보내도록 한다.
2. Provider 정의
import React, { createContext, useState, useEffect } from "react";
export const AppContext = createContext();
export function AppProvider({ children }) {
//상태, 함수 선언
return (
<AppContext.Provider
value={{
modalTypeToOpen,
openAddRestaurantModal,
handleClickedRestaurantInfo,
restaurants,
handleUpdatedRestaurants,
handleCloseModal,
clickedRestaurantInfo,
category,
handleCategoryChange,
filteredRestaurants,
}}
>
{children}
</AppContext.Provider>
);
}
-> 사용할 상태와 함수 로직들을 작성하고 return에서 AppContext.Provider를 통해 공유할 값을 전달한다.
-> 이때 Provider의 의미는 상태와 조작함수를 하나의 큰 객체로 묶어 자식에게 공급하는 의미를 가진다.
-> 즉, 이렇게 하면 Provider 하위에 있는 모든 컴포넌트가 value 객체에 접근할 수 있다.
3. useContext로 소비
const { 상태 or 함수 } = useContext(AppContext);
-> 하위 컴포넌트에서 위와같이 호출해서 필요한 만큼 꺼내 쓸 수 있다.
Context API 사용예시
1. Context 생성
// src/contexts/ThemeContext.jsx
import { createContext } from 'react';
export const ThemeContext = createContext({
theme: 'light', // 기본값(light) 설정
toggleTheme: () => {}, // 빈 함수(타입 정의용)
});
2. Provider 정의
// src/contexts/ThemeContext.jsx
import React, { useState } from 'react';
import { ThemeContext } from './ThemeContext';
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () =>
setTheme(prev => (prev === 'light' ? 'dark' : 'light'));
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
// src/App.jsx
import React from 'react';
import { ThemeProvider } from './contexts/ThemeContext';
import Header from './components/Header';
function App() {
return (
<ThemeProvider>
<Header />
{/* 나머지 컴포넌트 */}
</ThemeProvider>
);
}
export default App;
3. useContext로 소비하기
// src/components/Header.jsx
import React, { useContext } from 'react';
import { ThemeContext } from '../contexts/ThemeContext';
export default function Header() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<header style={{
background: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#000' : '#fff',
padding: '1rem'
}}>
<h1>My App</h1>
<button onClick={toggleTheme}>
현재 테마: {theme}
</button>
</header>
);
}'프론트엔드 > React' 카테고리의 다른 글
| [React] 웹 브라우저 렌더링 과정 (feat. 일반 CSS와 Styled-Components의 차이) (0) | 2025.05.23 |
|---|---|
| [React] Styled Components를 이용해서 CSS 작성하기 (1) | 2025.05.20 |
| [React] 콜백함수란? (0) | 2025.04.05 |
| [React] useState() 사용해서 카테고리 정렬하기(map, filter사용) (1) | 2025.04.05 |
| [React] filter()를 활용한 정렬하기 (0) | 2025.04.05 |