☘️ 시작하기 앞서...
나는 지금까지 프로젝트를 진행하면서 Prop Drilling 문제를 해결하기 위해 전역 상태 관리 라이브러리인 Redux, Recoil, Zustand 를 사용해 본 경험이 있었다. (완전 얕게...) 그리고 form 데이터는 React Hook Form 의 formProvider 를 사용해 보았다.
그런데 웃기게도 React 에 기본적으로 내장되어 있는 전역 상태를 할 수 있는 Context API 를 모르고 있었고 사용해 본 경험이 없었다.
하지만 코드잇 강의를 들으면서 Context API 에 대해 배우게 되었고 그 이후에 프로젝트에 직접 적용해 보고 그전에 사용해 본 상태관리 라이브러리와 비교해서 어떤 점에 장단점이 있는지 알게 되었다.
그래서 이번 글에서는 Context API 를 사용하는 방법에 대해 알아볼 것이다.
☘️ 전역 상태 관리 이유
React 에서 전역 상태 관리를 사용하는 이유가 무엇일까?
위에서 잠깐 말했다시피 Prop Drilling 문제를 해결하기 위해 전역 상태를 한다.
Prop Drilling
드릴로 땅을 파듯이, 상위 컴포넌트에서 하위 컴포넌트로 반복해서 Prop 을 내려주는 상황
Prop Drilling 단점
- 가독성 저하
- 컴포넌트가 분리되고 많아질 수로 Props 로만 데이터를 전달하면 코드가 복잡해진다.
- 성능 저하
- 중간중간에 필요하지 않은 데이터가 컴포넌트에 전달되어 불필요한 렌더링이 발생한다.
- 유지보수 어려움
- 많은 컴포넌트를 거쳐가기 때문에 특정 Props 의 이름이나 형식이 바뀌면 모든 컴포넌트에서 변경해야 한다.
- 재사용 어려움
- 컴포넌트끼리 밀접하게 결합이 된다.
그래서 이를 해결하기 위해 전역 상태 라이브러리(Redux, Recoil, Zustand 등) 을 사용하거나 React 에 내장되어 있는 Context API 를 사용하여 간단하게 데이터를 관리할 수 있게 된다.
☘️ Context API
Context 이란?
먼저 Context 란 무엇일까?
Context
많은 컴포넌트에서 사용하는 데이터를 반복적인 Prop 전달(Prop Drilling) 없이 공유
☘️ Context API 사용 방법
Context API 를 사용하는 방법은 간단하게 아래와 같다.
- Context 생성
- Provider 생성
- Consumer 생성
- Provider 감싸기
- 사용하기
1. context 생성
Reac 에 내장되어 있는 createContext 메서드를 사용하여 Context 를 생성한다.
아래는 imageUrl 을 전역 상태 관리하기 위한 Context 이고, createContext 메서드를 사용하여 context 를 생성한다.
그러면 값을 제공하는 Provider 와 값을 소비하는 Consumer 를 포함하는 객체 ImageUrlContext 가 리턴된다.
import { createContext, useContext, useState } from 'react';
// context 생성
const ImageUrlContext = createContext();
2. Provider 생성
context 의 값을 제공(전달)하기 위한 Provider 를 생성한다.
imageUrl 을 관리하는 Provider 를 생성하고,
하위 컴포넌트에게 imageUrl 값과 이를 수정할 setImageUrl 값을 넘겨주기 위해 value 에 값들을 넣는다.
export const ImageUrlProvider = ({ defaultValue = null, children }) => {
const [imageUrl, setImageUrl] = useState(defaultValue);
return (
<ImageUrlContext.Provider value={{ imageUrl, setImageUrl }}>
{children}
</ImageUrlContext.Provider>
);
};
3. Consumer 생성
하위 컴포넌트에서 imageUrl 과 setImageUrl 을 간편하게 사용할 수 있도록 Consumer 를 만들어준다.
useContext 를 사용하여 context 의 값을 소비할 수 있게 된다.
// imgUrl 값 가져오기
export const useImageUrl = () => {
const context = useContext(ImageUrlContext);
return context.imageUrl;
};
// setImageUrl 값 가져오기
export const useSetImageUrl = () => {
const context = useContext(ImageUrlContext);
return context.setImageUrl;
};
4. Provider 감싸기
이제 Context API 를 사용할 컴포넌트의 상위에 위에서 생성한 Provider 로 감싸준다.
나는 그냥 router 에서 감싸주었다. 그러면 이제 AddItemPage 하위에서는 위에서 만든 imageUrl 과 setImageUrl 을 아무 곳에서 간편하게 사용할 수 있게 된다.
import { ImageUrlProvider } from 'contexts/ItemImageContext';
...
{
path: '/addItem',
element: (
<ImageUrlProvider>
<AddItemPage />
</ImageUrlProvider>
),
},
5. 사용하기
하위 컴포넌트에서 위에서 만든 useImageUrl 과 useSetImageUrl 을 가져와서 해당 값을 사용하면 된다!
그러면 이제 이 값들을 사용해 전역적으로 사용할 수 있게 된다.
import { useImageUrl, useSetImageUrl } from 'contexts/ItemImageContext';
...
const imageUrl = useImageUrl();
const setImageUrl = useSetImageUrl();
☘️ 마치며...
react 에 기본적으로 내장되어 있는 context api 에 대해 알아보았다.
props 로 전달하기 복잡하고 번거로운 상황에서 context api 를 사용하여 전역 상태 관리를 할 수 있어 유용한 것 같다!
따로 라이브러리를 설치하지 않아도 되고 전역 상태 관리를 해야 될 것이 적으면 context api 를 사용하는 게 유용하다
그래서 이번 프로젝트에서도 credit 를 전역적으로 관리하기 위해 사용했었고 정말 편리하고 유용했다!
'💜 리액트 > React' 카테고리의 다른 글
[React] memo, useMemo, useCallback 사용해서 렌더링 최초화 하기!! (1) | 2024.06.10 |
---|---|
[React] 프로젝트 JavaScript 에서 TypeScript 마이그레이션 방법 (0) | 2024.05.26 |
[VS Code] React 코드 스닛펫(snippet) 커스텀 만들기 방법 (0) | 2024.05.07 |
[React] 렌더링 방식 CSR, SSR, SSG & CSS-in-JS의 장점과 단점 (2) | 2024.04.29 |
[React] key Props를 사용하는 이유 & 리액트 생명주기 (1) | 2024.04.21 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!