Studying/React

리액트 공부하기 - 전역 상태 관리 context API

creamymood 2025. 4. 24. 18:30

후.. 여행 후, 현생 복귀란 쉽지 않네요

하지만,, 다시 제 자리에서 집중 ! 


상태관리에서 createContext, Provider, useContext 이런 것들은 React에서 컴포넌트끼리 데이터를 공유하기 위해 사용하는 도구

🐰 먼저 큰 그림 (상위 개념)

상태 관리(State Management)란?

  • 컴포넌트들이 "공통된 정보"를 공유할 때 그 정보를 어디에 저장하고, 어떻게 전달하냐는 문제야.
  • 예: 로그인된 유저 정보, 언어 설정, 테마 같은 것들

상태 관리의 종류

  1. 로컬 상태 (useState) → 한 컴포넌트 안에서만 사용
  2. 전역 상태 → 여러 컴포넌트에서 공유해야 할 때 필요
    이 전역 상태를 도와주는 게 Context API야.

📦 Context API란?

전역 상태를 쉽게 관리할 수 있게 도와주는 도구 세트!

핵심 3개만 기억하면 돼:

  • createContext
  • Provider
  • useContext

 

🛠️ 각각 역할과 흐름

1. createContext

  • 일종의 박스 만들기야.
  • 이 박스에 데이터를 넣어두고, 어디서든 꺼내 쓸 수 있게 하려는 거야.
import { createContext } from 'react';

export const MyContext = createContext(); // 박스 하나 만든 거야

2. Provider

  • 만든 박스를 감싸는 포장지 같은 거야.
  • 자식 컴포넌트들한테 "이 박스 안에 든 걸 줄게!" 라는 역할.
<MyContext.Provider value={내가공유할값}>
  <App />   // 이 App과 그 자식들은 이제 그 "값"을 꺼내 쓸 수 있어
</MyContext.Provider>

3. useContext

  • 자식 컴포넌트에서 박스 안 데이터를 꺼내 쓰는 도구야.
import { useContext } from 'react';
import { MyContext } from './MyContextFile';

const Child = () => {
  const value = useContext(MyContext);  // 박스에서 값 꺼냄
  return <div>{value}</div>;
};

💡 실제 흐름 요약 (예시)

  1. MyContext라는 박스 만들고
  2. MyContext.Provider로 App 또는 공유가 필요한 컴포넌트들을 감싸고
  3. 그 내부의 자식 컴포넌트에서 useContext(MyContext)로 꺼내 씀

🧪 예제 코드로 한 눈에 보기

// context/UserContext.js
import { createContext } from 'react';

export const UserContext = createContext();

 

// App.jsx
import { UserContext } from './context/UserContext';
import Child from './Child';

function App() {
  const user = 'Jane';

  return (
    <UserContext.Provider value={user}>
      <Child />
    </UserContext.Provider>
  );
}
// Child.jsx
import { useContext } from 'react';
import { UserContext } from './context/UserContext';

const Child = () => {
  const user = useContext(UserContext);
  return <p>Hello, {user}!</p>;
};

 



Provider로 값을 넣을 때는 정말 거의 뭐든지 넣을 수 있어.
단! value={} 이 안에 들어가는 건 단 하나의 값만 가능해.
그게 객체든 문자열이든 함수든 배열이든 다 돼!


✅ 어떤 걸 넣을 수 있냐면:

1. 문자열

<UserContext.Provider value="Jane">

2. 숫자

<CountContext.Provider value={42}>

3. 객체 (가장 많이 씀!!)

<UserContext.Provider value={{ name: "Jane", age: 28 }}>

4. 배열

<ThemeContext.Provider value={["dark", "light"]}>

5. 함수 (상태 변경 함수 등!)

<MyContext.Provider value={() => alert("Hi!")}>

6. 복합 형태 (객체 안에 상태랑 함수 둘 다 넣기)

<MyContext.Provider value={{
  user: "Jane",
  setUser: setUser, // 상태 변경 함수
}}>

이 구조가 진짜 많이 쓰여.
예: 로그인한 유저 정보랑 로그아웃 함수 같이 전달할 때


🔄 왜 객체로 많이 쓰냐면?

여러 값을 한 번에 보내고 싶을 때 편하거든!

const value = {
  theme: "dark",
  toggleTheme: () => setTheme(prev => prev === "dark" ? "light" : "dark")
};

<ThemeContext.Provider value={value}>

그럼 자식 컴포넌트에선:

const { theme, toggleTheme } = useContext(ThemeContext);

이렇게 편하게 구조분해 해서 꺼낼 수 있어!


🚨 잠깐! 주의할 점

  • value={}에는 하나의 값만 들어간다.
  • 여러 값을 보내고 싶으면 객체로 묶어서 보내야 돼.
  • 상태(useState)랑 같이 쓰면 진짜 강력해져.

👩🏻‍💻 알게 된 점

- createContext 부분에는 컴포넌트를 만드니까 오류가 나더라..

- provider 부분과, createContext는 분리 해줘야할 것.

- provider 컴포넌트 만든 뒤, app이나 main에서 묶어줘야할 것