[React] Context API

seungjun.dev·3일 전
0

React

목록 보기
10/11

Context API

Props Drilling 문제 해결 방법 중 하나

컴포넌트 트리 전반에 걸쳐 데이터를 효율적으로 공유할 수 있게 해주는 기능이다.

Context를 사용하면, 데이터를 필요로 하는 컴포넌트가 트리 구조상 어디에 있든 상관없이 Provider로부터 직접 데이터에 접근할 수 있다.

Context API 핵심 구성 요소

  1. createContext: 컨텍스트 객체 생성
  2. Context.Provider: 생성된 컨텍스트를 하위 컴포넌트들에게 제공(Provide), value prop을 통해 공유할 데이터를 전달
  3. useContext: Provider가 제공한 데이터에 접근(Consume)하는 훅

사용법

1. Context 생성

import type { AccommodationType } from '@/types/accommodationType';
import { createContext } from 'react';

const AccommodationContext = createContext<AccommodationType | null>(null);

export const AccommodationProvider = AccommodationContext.Provider;

export default AccommodationContext;

createContext를 사용해 컨텍스트 객체를 생성한다.

import AccommodationContext from '@/features/search/contexts/AccommodationContext';
import { useContext } from 'react';

const useAccommodation = () => {
  const context = useContext(AccommodationContext);

  if (!context) {
    throw new Error(
      'useAccommodation은 AccommodationProvider 내에서만 사용 가능',
    );
  }
  return context;
};

export default useAccommodation;

이때 커스텀 훅을 함께 만들어두면, 컨텍스트를 사용할 때마다 발생하는 특정 반복 작업을 줄이고 코드를 깔끔하게 유지할 수 있다.

여기서는 훅이 프로바이더 내부에서만 사용되도록 했다. (context === null인 경우)

2. Provider로 감싸기

const AccommodationList = ({
  accommodations,
}: {
  accommodations: AccommodationResponse;
}) => {
  return (
    <AccommodationListContainer>
      {accommodations?.map((item: AccommodationType) => (
        <AccommodationProvider key={item.accommodation_id} value={item}>
          <Accommodation />
        </AccommodationProvider>
      ))}
      <Divider width="100%" />
    </AccommodationListContainer>
  );
};

데이터 공유가 필요한 컴포넌트 트리의 최상단에서 Provider 컴포넌트로 하위 컴포넌트들을 감싸준다.

3. 데이터 사용

const Accommodation = () => {
  const accommodation = useAccommodation();

  return (
    <AccommodationContainer>
      <AccommodationImg src={accommodation.accommodation_photo_url} />
      <AccommodationInfo />
    </AccommodationContainer>
  );
};

위에서 구현한 커스텀 훅으로 데이터에 바로 접근할 수 있다.

Context API의 부작용

불필요한 리렌더링

  • Providervalue prop이 변경되면, 해당 컨텍스트를 useContext로 구독(사용)하고 있는 모든 하위 컴포넌트가 리렌더링된다.
  • value prop에 매번 새로운 객체를 전달하면, 부모 컴포넌트가 리렌더링될 때마다 value가 새롭게 인식되어 컨텍스트를 사용하는 모든 자식이 리렌더링된다.

해결책 (최적화)

  • useMemo / useCallback: value로 전달되는 객체나 함수를 useMemouseCallback으로 메모이제이션하여 불필요한 재생성을 방지한다.
  • 컨텍스트 분리: 하나의 거대한 컨텍스트에 모든 전역 상태를 넣지 말자.
    • 상태가 자주 변경되는 부분과 거의 변경되지 않는 부분은 별도의 컨텍스트로 분리한다.
profile
Web FE Dev | Microsoft Student Ambassadors Alumni

0개의 댓글