[리액트] Context API 실습

journey·2025년 7월 8일

🧾 Context vs Props 정리 요약

✅ 1. props 방식의 한계

예시 구조

App.tsx
 └── NonContext.tsx
       └── GrandParent.tsx
             └── Parent.tsx
                   └── Child.tsx
                         └── GrandChild.tsx

❗ 문제점: Props Drilling 발생

  • 하위 컴포넌트로 데이터를 넘기기 위해 중간 컴포넌트들도 모두 props를 받아야 함

  • 중간 컴포넌트가 props를 직접 쓰지도 않는데 단지 전달만 함

  • 이런 현상을 👉 props drilling이라고 부름


🚫 props drilling의 단점

  1. 유지보수 어려움
    → 중간 컴포넌트를 건드릴 일 없이 값만 바꾸고 싶은데도, 파일 여러 개를 수정해야 함

  2. 재사용성 낮음
    → 중간 컴포넌트가 특정 props에 의존하게 되면 재사용이 어려워짐

  3. 타입 변경 시 불편함 (TypeScript)
    → props의 이름이나 타입이 바뀌면 전달 경로의 모든 interface를 수정해야 함
    → 타입스크립트는 정적 타입 언어라 컴파일 에러 발생

✅ 2. Context를 쓰면?

해결 방법: Context API

여러 컴포넌트에서 공유해야 하는 데이터는 전역 저장소처럼 Context에 저장하고,
하위 컴포넌트에서는 props 없이도 바로 꺼내 쓰게 해준다.

🔁 Context API 사용 순서

단계설명
1. createContext()공유할 데이터의 틀 생성
2. Context.Provider값을 실제로 공급함 (보통 최상단에서 감쌈)
3. useContext()하위 컴포넌트에서 값 꺼내 쓰기

✅ Context의 장점

장점
props 없이 하위 컴포넌트에서 전역 데이터 사용 가능
중간 컴포넌트는 props를 몰라도 됨
코드가 간결하고 명확해짐
상태와 UI가 느슨하게 연결되어, 유지보수성 증가

예시코드

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

/* 
1. Context 생성 -> 공유할 값의 타입과 초기값을 정의
여기서 createContext로 생성한 객체를 useContext로 가져와서 사용
*/ 
const CountContext = createContext({
  count: 0,
  plusCount: () => {},
});

/*
 2. 타입 정의 
*/
interface Props {
  children: JSX.Element | JSX.Element[];
}

/*
3. CountProvider 컴포넌트 정의
*/
const CountProvider = ({ children }: Props): JSX.Element => {
  const [count, setCount] = useState(0);

  const plusCount = (): void => {
    setCount(count + 1);
  };

  return (
    <CountContext.Provider
      value={{
        count,
        plusCount,
      }}
    >
      {children}
    </CountContext.Provider>
  );
};

/*
4. CountContext와 CountProvider를 export
*/
export { CountContext, CountProvider };

✅ 최종 요약: Context 작성 흐름

  1. createContext() → 공유할 데이터 틀 정의
  2. (필요 시) Props 인터페이스 정의
  3. Provider 컴포넌트 작성 → 내부에서 state, 함수 정의
  4. Provider에서 Context.Provider로 감싸기 + value 전달
  5. Context / Provider export
const CountContext = createContext({
  count: 0,
  plusCount: () => {},
});

이 CountContext는 사실 내부적으로 이런 두 가지 속성을 가진 객체

{
  Provider: 리액트 제공자 컴포넌트,
  Consumer: 리액트 구독자 컴포넌트
}

그래서 우리는 CountContext.Provider처럼 점(.)으로 접근해서
Provider 컴포넌트를 꺼내서 사용하는 거

profile
개발 여정

0개의 댓글