Notice
Recent Posts
Recent Comments
Link
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

꽃 같은 인생

React&Redux ✨ React - 상태관리 심화 🌈 본문

카테고리 없음

React&Redux ✨ React - 상태관리 심화 🌈

flo-jee 2025. 2. 27. 22:03

🌐 React 전역 상태관리 개념 정리 노트 🌐


🎯 1. 전역 상태관리의 장점

  • 리액트대표적인 SPA라이브러리이고 SPA구현방법은 상태변경 → 리렌더링 이기에 상태를 잘 관리 하는 것이 매우 중요하다.

🎨 리액트 전역 상태 관리 개념

  • 리액트 전역 상태 관리여러 컴포넌트 간 데이터 공유를 효율적으로 처리하는 방법.
  • 로컬 상태(useState)로는 관리하기 어려운 글로벌 데이터(예: 사용자 정보, 테마 설정, 로그인 상태 등)를 전역에서 일관되게 사용할 수 있다.
  • 전역 상태 관리가 필요한 이유:
    • props drilling 문제 해결
    • ♻️ 반복적인 데이터 전달 방지
    • 🔗 컴포넌트 간 상태 일관성 유지

📌 데이터 일관성 및 유지보수

  • 여러 컴포넌트에서 동일한 데이터를 공유할 때 중앙에서 관리하여 일관성 유지가 가능
  • 상태가 한 곳에서 관리되기 때문에 버그 추적수정이 용이.
  • 전역 상태를 활용하면 대규모 프로젝트에서도 유지보수성이 높아짐

🔗 Props Drilling 문제

  • 정의: 부모 컴포넌트에서 자식, 손자 컴포넌트로 데이터를 계속 전달하는 방식
  • 문제점:
    • 중간 컴포넌트가 데이터를 실제로 사용하지 않아도 전달만 해야 해서 코드가 복잡해진다.
    • 컴포넌트 구조가 복잡해질수록 가독성 저하유지보수성 악화가 발생할 수 있다.

💡 전역 상태 관리의 필요성

  • Props Drilling 문제 해결: 복잡한 컴포넌트 구조에서 불필요한 props 전달 없이 데이터를 쉽게 공유할 수 있다.
  • 중앙 집중형 관리: 여러 컴포넌트가 동일한 데이터를 공유할 때, 중앙 집중형 관리를 통해 효율성을 높일 수 있다.
  • 규모 확장성: 애플리케이션 규모가 커질수록 상태 동기화 문제버그 발생 위험을 줄일 수 있다.

🌟 리액트 전역 상태 관리 방법

🔥 방법 🌟 설명 💡 장점 ⚡ 단점

🎨 Props Drilling 부모에서 자식 컴포넌트로 props를 통해 데이터 전달 단순 구현, 기본 React 기능만 사용 트리 깊을수록 관리 어려움
🌿 Context API createContext와 useContext로 전역 상태 공유 간단한 전역 상태 관리, props drilling 해결 대규모 앱에서 성능 문제 발생 가능
💎 Redux 상태를 store에 저장하고 action, reducer로 업데이트 대규모 앱에서 일관된 상태 관리 보일러플레이트 코드 많음
🚀 Redux Toolkit Redux 설정을 간소화하고 코드량을 줄이는 표준 툴킷 간결한 코드, DevTools 통합 지원 Redux 개념 이해 필요

⚛️ 2. React 내부 구현 상태관리

🌿 내부 상태 관리 방법

useState

  • 간단한 상태 관리를 위한 기본적인 React Hook이다.
  • 컴포넌트 내부에서 상태를 선언하고 갱신하는 데 사용된다.
  • 💡 예시 코드:
  • import React, { useState } from 'react'; const Counter = () => { const [count, setCount] = useState(0); return ( <div> <p>카운트: {count}</p> <button onClick={() => setCount(count + 1)}>증가</button> </div> ); }; export default Counter;

useReducer

  • 복잡한 상태 로직이나 다수의 상태 값을 다룰 때 사용돼.
  • 리듀서 패턴을 통해 상태를 체계적으로 관리할 수 있어.
  • 💡 예시 코드:
  • import React, { useReducer } from 'react'; const reducer = (state, action) => { switch (action.type) { case 'INCREMENT': return { count: state.count + 1 }; case 'DECREMENT': return { count: state.count - 1 }; default: return state; } }; const Counter = () => { const [state, dispatch] = useReducer(reducer, { count: 0 }); return ( <div> <p>카운트: {state.count}</p> <button onClick={() => dispatch({ type: 'INCREMENT' })}>증가</button> <button onClick={() => dispatch({ type: 'DECREMENT' })}>감소</button> </div> ); }; export default Counter;

🌈 Context API

📌 개념

  • 전역 상태를 손쉽게 관리할 수 있는 React 내장 기능
  • createContext, Provider, useContext를 사용해 구현
  • 컴포넌트 트리 전체에 데이터를 전달하여 props drilling 문제를 해결

🌟 특징

  • 별도의 라이브러리 없이 전역 상태 공유가 가능
  • 단순한 구조로 빠르게 구현할 수 있지만, 빈번한 업데이트성능 이슈에 주의

💡 Context API 사용 예시

// 📁 context/UserContext.js
import React, { createContext, useState, useContext } from 'react';

const UserContext = createContext();

export const UserProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  return (
    <UserContext.Provider value={{ user, setUser }}>
      {children}
    </UserContext.Provider>
  );
};

export const useUser = () => useContext(UserContext);
// 📁 App.js
import React from 'react';
import { UserProvider, useUser } from './context/UserContext';

const Profile = () => {
  const { user } = useUser();
  return <div>{user ? `안녕하세요, ${user.name}님!` : '로그인해주세요.'}</div>;
};

const App = () => (
  <UserProvider>
    <Profile />
  </UserProvider>
);

export default App;

⚖️ 장단점

  • 장점: 간단하고 props drilling 문제 해결
  • ⚠️ 단점: 대규모 앱에서 성능 저하 발생 가능

🚀 3. React 외부 구현 상태관리

🌍 외부 상태 관리 방법

  • 전용 상태관리 라이브러리를 사용하여 복잡한 상태 관리 문제를 해결할 수 있어.
  • 주요 라이브러리:
    • Redux
    • Redux Toolkit
    • 기타: MobX, Recoil, Zustand

💎 Redux & Redux Toolkit

📌 Redux

  • 특징:
    • 모든 상태를 **하나의 스토어(Store)**에 저장.
    • *액션(Action)**과 **리듀서(Reducer)**를 통해 상태 변경을 관리.
    • 단방향 데이터 흐름으로 디버깅유지보수가 용이해.
  • 💡 Redux의 장점: 대규모 프로젝트에서 예측 가능한 상태 관리디버깅 편의성 제공.

Redux Toolkit

  • 목적: Redux 사용 시 발생하는 보일러플레이트 코드를 줄여 간편하게 사용할 수 있도록 해.
  • 내장 기능:
    • createSlice: 액션과 리듀서를 한 번에 생성.
    • createAsyncThunk: 비동기 로직 간편 처리.
  • 💡 Redux Toolkit 추천 이유:복잡한 상태 관리를 더 효율적이고 직관적으로 구현할 수 있어.

💡 Redux Toolkit 사용 예시

npm install @reduxjs/toolkit react-redux
// 📁 store.js
import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) => { state.value += 1; },
    decrement: (state) => { state.value -= 1; },
  },
});

export const { increment, decrement } = counterSlice.actions;

const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

export default store;
// 📁 App.js
import React from 'react';
import { Provider, useSelector, useDispatch } from 'react-redux';
import store, { increment, decrement } from './store';

const Counter = () => {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div className="p-4 text-center">
      <h1 className="text-3xl mb-4">카운트: {count}</h1>
      <button className="px-4 py-2 bg-green-500 text-white mr-2" onClick={() => dispatch(increment())}>
        증가
      </button>
      <button className="px-4 py-2 bg-red-500 text-white" onClick={() => dispatch(decrement())}>
        감소
      </button>
    </div>
  );
};

const App = () => (
  <Provider store={store}>
    <Counter />
  </Provider>
);

export default App;

전역 상태관리 요약

💡 개념 🌟 설명 💎 장점 ⚠️ 단점

Props Drilling 상위 컴포넌트에서 하위로 props 전달 간단한 구조에서 적합 깊은 트리에서 비효율적
🌿 Context API React 내장 전역 상태관리 도구 별도 설치 없이 사용 가능 큰 상태 변경 시 리렌더링 발생
🚀 Redux 중앙 집중식 상태 관리 대규모 앱에 적합, 강력한 생태계 초기 설정 복잡
🎯 Redux Toolkit Redux를 더 쉽게 사용하도록 도와주는 공식 툴킷 간편한 설정, 비동기 지원 내장 러닝커브 존재

⚛️ React 상태관리 심화 노트 ⚛️


🎨 1. 리액트 전역 상태 관리 개념

  • 리액트 전역 상태 관리여러 컴포넌트 간 데이터 공유를 효율적으로 처리하는 방법.
  • 로컬 상태(useState)로는 관리하기 어려운 글로벌 데이터(예: 사용자 정보, 테마 설정, 로그인 상태 등)를 전역에서 일관되게 사용할 수 있다.
  • 전역 상태 관리가 필요한 이유:
    • props drilling 문제 해결
    • ♻️ 반복적인 데이터 전달 방지
    • 🔗 컴포넌트 간 상태 일관성 유지

🌟 2. 리액트 전역 상태 관리 방법

🔥 방법 🌟 설명 💡 장점 ⚡ 단점

🎨 Props Drilling 부모에서 자식 컴포넌트로 props를 통해 데이터 전달 단순 구현, 기본 React 기능만 사용 트리 깊을수록 관리 어려움
🌿 Context API createContext와 useContext로 전역 상태 공유 간단한 전역 상태 관리, props drilling 해결 대규모 앱에서 성능 문제 발생 가능
💎 Redux 상태를 store에 저장하고 action, reducer로 업데이트 대규모 앱에서 일관된 상태 관리 보일러플레이트 코드 많음
🚀 Redux Toolkit Redux 설정을 간소화하고 코드량을 줄이는 표준 툴킷 간결한 코드, DevTools 통합 지원 Redux 개념 이해 필요

🌿 3. Props Drilling 실습

🌿 개념

  • 상위 컴포넌트가 하위 컴포넌트로 데이터를 전달할 때 여러 단계를 거치는 현상.

💡 예시 코드

const Child = ({ message }) => <p>{message}</p>;

const Parent = ({ message }) => <Child message={message} />;

const App = () => {
  const message = "Hello from App!";
  return <Parent message={message} />;
};

export default App;

⚖️ 장단점

  • 장점: 단순하고 React 기본 기능만 사용
  • ⚠️ 단점: 트리가 깊어질수록 데이터 전달이 복잡해짐

💎 4. Context API

🌟 개념

  • 전역 상태를 손쉽게 관리할 수 있는 React 내장 기능.
  • createContext, Provider, useContext를 사용해 구현.

💡 예시 코드

import React, { createContext, useContext, useState } from 'react';

const MessageContext = createContext();

const MessageProvider = ({ children }) => {
  const [message, setMessage] = useState("Hello from Context!");
  return (
    <MessageContext.Provider value={{ message, setMessage }}>
      {children}
    </MessageContext.Provider>
  );
};

const Child = () => {
  const { message } = useContext(MessageContext);
  return <p>{message}</p>;
};

const App = () => (
  <MessageProvider>
    <Child />
  </MessageProvider>
);

export default App;

⚖️ 장단점

  • 장점: 간단하고 props drilling 문제 해결
  • ⚠️ 단점: 대규모 앱에서 성능 저하 발생 가능

🎁 Redux

개념

  • 전역 상태를 중앙 집중화하여 관리하는 예측 가능한 상태 컨테이너.
  • 상태를 store에 저장하고 action, reducer를 통해 업데이트.

💡 예시 코드

// store.js
import { createStore } from 'redux';

const initialState = { count: 0 };
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
};

const store = createStore(reducer);
export default store;
// App.js
import React from 'react';
import { Provider, useSelector, useDispatch } from 'react-redux';
import store from './store';

const Counter = () => {
  const count = useSelector((state) => state.count);
  const dispatch = useDispatch();
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
    </div>
  );
};

const App = () => (
  <Provider store={store}>
    <Counter />
  </Provider>
);

export default App;

⚖️ 장단점

  • 장점: 대규모 앱에서 일관성 있는 상태 관리
  • ⚠️ 단점: 설정이 복잡하고 보일러플레이트 코드가 많음

🎛️ Redux Toolkit

🚀 개념

  • Redux 설정을 간소화하고 표준화된 상태 관리를 제공하는 툴킷.
  • createSlice, configureStore 등으로 구현 단순화.

💡 예시 코드

// counterSlice.js
import { createSlice, configureStore } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { count: 0 },
  reducers: {
    increment: (state) => {
      state.count += 1;
    },
  },
});

export const { increment } = counterSlice.actions;

const store = configureStore({
  reducer: counterSlice.reducer,
});

export default store;
// App.js
import React from 'react';
import { Provider, useSelector, useDispatch } from 'react-redux';
import store, { increment } from './counterSlice';

const Counter = () => {
  const count = useSelector((state) => state.count);
  const dispatch = useDispatch();
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch(increment())}>Increment</button>
    </div>
  );
};

const App = () => (
  <Provider store={store}>
    <Counter />
  </Provider>
);

export default App;

⚖️ 장단점

    • 장점: 간결한 코드, Redux 설정 자동화, DevTools 통합 지원
    • ⚠️ 단점: Redux의 기본 개념에 대한 이해 필요

      ⚛️ Props Drilling 실습 노트 ⚛️

      1️⃣ Props Drilling 개념
      • Props Drilling은 데이터를 상위 컴포넌트에서 하위 컴포넌트로 props를 통해 전달하는 방식이야.
      • 컴포넌트 트리에서 여러 단계를 거쳐 데이터를 전달해야 할 때 발생해.
      • 전역 상태 관리 도구 없이도 데이터 전달이 가능하지만, 컴포넌트가 많아질수록 유지보수가 어려워질 수 있어.
      🔑 왜 Props Drilling이 문제가 될까?
      • 중간 컴포넌트가 데이터에 관심이 없음에도 props를 전달해야 하는 상황 발생
      • 트리 깊이가 깊어질수록 코드의 가독성 및 유지보수성이 떨어짐
      • 불필요한 리렌더링 발생 가능성 증가

      2️⃣ Props Drilling 예제
      // Child.js
      const Child = ({ message }) => <p>{message}</p>;
      
      // Parent.js
      const Parent = ({ message }) => <Child message={message} />;
      
      // App.js
      const App = () => {
        const message = "Hello from App!";
        return <Parent message={message} />;
      };
      
      export default App;
      
      📝 예제 설명
      • App 컴포넌트에서 생성된 message가 Parent를 거쳐 Child에 전달돼.
      • Parent는 message를 직접 사용하지 않지만, 전달자 역할만 수행해.

      3️⃣ 복잡한 Props Drilling 예시
      const LevelThree = ({ message }) => <p>{message}</p>;
      
      const LevelTwo = ({ message }) => <LevelThree message={message} />;
      
      const LevelOne = ({ message }) => <LevelTwo message={message} />;
      
      const App = () => {
        const message = "Hello from the top!";
        return <LevelOne message={message} />;
      };
      
      export default App;
      
      📝 예제 설명
      • App에서 생성된 message가 LevelOne → LevelTwo → LevelThree까지 전달돼.
      • 트리의 깊이가 깊어질수록 props 전달이 반복되어 코드의 복잡성이 증가해.

      4️⃣ Props Drilling의 문제점
      • 중간 컴포넌트가 불필요한 props를 수신하고 전달해야 함
      • 유지보수 어려움: 컴포넌트가 많아질수록 props 전달 경로를 따라가기 힘듦
      • 성능 문제: 중간 컴포넌트가 필요하지 않은 상태 변경에도 리렌더링됨
      🛠️ 해결 방법
      • Context API 사용
      • 전역 상태 관리 도구 사용 (Redux, Zustand 등)
      • 컴포넌트 재구조화하여 필요한 데이터만 전달

      5️⃣ Props Drilling 문제 해결: Context API 사용 예시
      import React, { createContext, useContext, useState } from 'react';
      
      const MessageContext = createContext();
      
      const MessageProvider = ({ children }) => {
        const [message] = useState("Hello from Context!");
        return (
          <MessageContext.Provider value={message}>
            {children}
          </MessageContext.Provider>
        );
      };
      
      const LevelThree = () => {
        const message = useContext(MessageContext);
        return <p>{message}</p>;
      };
      
      const LevelTwo = () => <LevelThree />;
      
      const LevelOne = () => <LevelTwo />;
      
      const App = () => (
        <MessageProvider>
          <LevelOne />
        </MessageProvider>
      );
      
      export default App;
      
      📝 예제 설명
      • useContext 훅을 사용하여 중간 컴포넌트를 거치지 않고 상태를 직접 접근할 수 있어.
      • props drilling 문제 해결리렌더링 최적화 가능.

      6️⃣ Props Drilling 요약 정리🔥 항목 🌟 설명 💡 해결 방안
      🎨 개념 상위에서 하위로 props를 통해 데이터 전달 Context API, 전역 상태 관리 도구
      문제점 중간 컴포넌트의 불필요한 props 전달, 리렌더링 문제 컴포넌트 재구조화, 상태 분리
      🚀 해결 방법 Context API로 전역 상태 관리, Redux 활용 효율적인 상태 전달과 유지보수성 향상

      ✨💖 Props Drilling 개념과 실습을 통해 효율적인 데이터 전달 구조를 만들어
      1️⃣ Props Drilling 개념
      • Props Drilling은 데이터를 상위 컴포넌트에서 하위 컴포넌트로 props를 통해 전달하는 방식이야.
      • 컴포넌트 트리에서 여러 단계를 거쳐 데이터를 전달해야 할 때 발생해.
      • 전역 상태 관리 도구 없이도 데이터 전달이 가능하지만, 컴포넌트가 많아질수록 유지보수가 어려워질 수 있어.
      🔑 왜 Props Drilling이 문제가 될까?
      • 중간 컴포넌트가 데이터에 관심이 없음에도 props를 전달해야 하는 상황 발생
      • 트리 깊이가 깊어질수록 코드의 가독성 및 유지보수성이 떨어짐
      • 불필요한 리렌더링 발생 가능성 증가

      2️⃣ Props Drilling 예제
      // Child.js
      const Child = ({ message }) => <p>{message}</p>;
      
      // Parent.js
      const Parent = ({ message }) => <Child message={message} />;
      
      // App.js
      const App = () => {
        const message = "Hello from App!";
        return <Parent message={message} />;
      };
      
      export default App;
      
      📝 예제 설명
      • App 컴포넌트에서 생성된 message가 Parent를 거쳐 Child에 전달돼.
      • Parent는 message를 직접 사용하지 않지만, 전달자 역할만 수행해.

      3️⃣ 복잡한 Props Drilling 예시
      const LevelThree = ({ message }) => <p>{message}</p>;
      
      const LevelTwo = ({ message }) => <LevelThree message={message} />;
      
      const LevelOne = ({ message }) => <LevelTwo message={message} />;
      
      const App = () => {
        const message = "Hello from the top!";
        return <LevelOne message={message} />;
      };
      
      export default App;
      
      📝 예제 설명
      • App에서 생성된 message가 LevelOne → LevelTwo → LevelThree까지 전달돼.
      • 트리의 깊이가 깊어질수록 props 전달이 반복되어 코드의 복잡성이 증가해.

      4️⃣ Props Drilling의 문제점
      • 중간 컴포넌트가 불필요한 props를 수신하고 전달해야 함
      • 유지보수 어려움: 컴포넌트가 많아질수록 props 전달 경로를 따라가기 힘듦
      • 성능 문제: 중간 컴포넌트가 필요하지 않은 상태 변경에도 리렌더링됨
      🛠️ 해결 방법
      • Context API 사용
      • 전역 상태 관리 도구 사용 (Redux, Zustand 등)
      • 컴포넌트 재구조화하여 필요한 데이터만 전달

      5️⃣ Props Drilling 문제 해결: Context API 사용 예시
      import React, { createContext, useContext, useState } from 'react';
      
      const MessageContext = createContext();
      
      const MessageProvider = ({ children }) => {
        const [message] = useState("Hello from Context!");
        return (
          <MessageContext.Provider value={message}>
            {children}
          </MessageContext.Provider>
        );
      };
      
      const LevelThree = () => {
        const message = useContext(MessageContext);
        return <p>{message}</p>;
      };
      
      const LevelTwo = () => <LevelThree />;
      
      const LevelOne = () => <LevelTwo />;
      
      const App = () => (
        <MessageProvider>
          <LevelOne />
        </MessageProvider>
      );
      
      export default App;
      
      📝 예제 설명
      • useContext 훅을 사용하여 중간 컴포넌트를 거치지 않고 상태를 직접 접근할 수 있어.
      • props drilling 문제 해결리렌더링 최적화 가능.

      6️⃣ Props Drilling 요약 정리🔥 항목 🌟 설명 💡 해결 방안
      🎨 개념 상위에서 하위로 props를 통해 데이터 전달 Context API, 전역 상태 관리 도구
      문제점 중간 컴포넌트의 불필요한 props 전달, 리렌더링 문제 컴포넌트 재구조화, 상태 분리
      🚀 해결 방법 Context API로 전역 상태 관리, Redux 활용 효율적인 상태 전달과 유지보수성 향상

    • 🌟 Context API 사용 코드
    • ⚠️ 주요 문제점
    • 💡 컴포넌트 트리가 깊을 때
    • 💡 기본 예시 코드
    • 🌿 Props Drilling 실습 노트 🌿
    • 🌟 Context API 사용 코드
    • ⚠️ 주요 문제점
    • 💡 컴포넌트 트리가 깊을 때
    • 💡 기본 예시 코드

      🌐 전역 상태 관리: Context API 노트 🌐


      🌿 Context API란?

      • React 내장 전역 상태관리 도구이고 ****별도 설치 없이 사용 가능하다. 그러나 큰 상태 변경 시 리렌더링 발생한다.

1️⃣ Context API 개념

      • Context APIReact 내장 전역 상태 관리 도구로, 컴포넌트 트리의 깊이에 관계없이 데이터를 전달할 수 있다.
      • props drilling 문제를 해결하여 컴포넌트 간 데이터 공유를 간편하게 만들어준다.
      • 주요 구성 요소:
        • createContext: 컨텍스트 생성
        • Provider: 하위 컴포넌트에 데이터 전달
        • useContext: 하위 컴포넌트에서 데이터 접근

2️⃣ Context API 사용 시기

      • props drilling 문제가 발생할 때
      • 🌈 전역 테마 설정 (예: 다크 모드, 컬러 테마)
      • 🔑 인증 상태 관리 (로그인/로그아웃 상태)
      • 🌐 다국어 지원(Localization)
      • 📦 글로벌 데이터 공유 (사용자 정보, 장바구니 데이터 등)

3️⃣ Context API 기본 사용법

      • createContext로 전역상태 만들기
      • Provider로 전역상태 연결하기
      • useContext로 전역상태 가져오기

💡 간단한 예시 코드

    • import React, { createContext, useContext, useState } from 'react';
      
      // 1️⃣ Context 생성
      const UserContext = createContext();
      
      // 2️⃣ Provider 컴포넌트 생성
      const UserProvider = ({ children }) => {
        const [user, setUser] = useState({ name: 'Alice', age: 25 });
        return (
          <UserContext.Provider value={{ user, setUser }}>
            {children}
          </UserContext.Provider>
        );
      };
      
      // 3️⃣ Context 사용
      const Profile = () => {
        const { user } = useContext(UserContext);
        return (
          <div>
            <h2>👤 {user.name}</h2>
            <p>🎂 {user.age} years old</p>
          </div>
        );
      };
      
      // 4️⃣ App에서 Provider로 감싸기
      const App = () => (
        <UserProvider>
          <Profile />
        </UserProvider>
      );
      
      export default App;
      
      

📝 예제 설명

      • UserContext를 생성하여 사용자 정보를 전역으로 관리.
      • Profile 컴포넌트에서 useContext를 사용해 중간 컴포넌트를 거치지 않고 데이터를 직접 접근.

4️⃣ Context API 고급 사용법

    •  

🌟 useReducer와 함께 사용하기

      • 복잡한 상태 로직을 관리할 때 useReducer와 함께 사용하면 좋다.

💡 예시 코드

    • import React, { createContext, useReducer, useContext } from 'react';
      
      const CounterContext = createContext();
      
      const counterReducer = (state, action) => {
        switch (action.type) {
          case 'INCREMENT':
            return { count: state.count + 1 };
          case 'DECREMENT':
            return { count: state.count - 1 };
          default:
            return state;
        }
      };
      
      const CounterProvider = ({ children }) => {
        const [state, dispatch] = useReducer(counterReducer, { count: 0 });
        return (
          <CounterContext.Provider value={{ state, dispatch }}>
            {children}
          </CounterContext.Provider>
        );
      };
      
      const Counter = () => {
        const { state, dispatch } = useContext(CounterContext);
        return (
          <div>
            <p>🔢 Count: {state.count}</p>
            <button onClick={() => dispatch({ type: 'INCREMENT' })}>➕ Increment</button>
            <button onClick={() => dispatch({ type: 'DECREMENT' })}>➖ Decrement</button>
          </div>
        );
      };
      
      const App = () => (
        <CounterProvider>
          <Counter />
        </CounterProvider>
      );
      
      export default App;
      
      

📝 예제 설명

      • useReducer와 함께 사용하여 상태 관리 로직을 더 깔끔하고 예측 가능하게 관리.

5️⃣ Context API의 장단점

    •  

🌟 장점

      • props drilling 문제 해결
      • 간단한 설정과 사용 (별도의 라이브러리 필요 없음)
      • 컴포넌트 트리 전역 상태 공유

단점

      • ⚠️ 대규모 앱에서 성능 문제 발생 가능 (모든 하위 컴포넌트가 리렌더링됨)
      • ⚠️ 상태가 커질수록 복잡성 증가 (Redux 같은 도구가 더 적합할 수 있음)

6️⃣ Context API 요약 정리

  • 🔥 항목 🌟 설명 💡 예시
    🎨 핵심 기능 컴포넌트 트리 내 전역 상태 제공 테마 설정, 다국어 지원
    사용 시기 props drilling 문제 발생, 간단한 전역 상태 필요할 때 로그인 상태, 사용자 정보 공유
    🚀 고급 사용법 useReducer와 결합하여 복잡한 상태 로직 처리 카운터 기능, 폼 데이터 관리
    💎 성능 최적화 상태 분리, React.memo 사용하여 불필요한 렌더링 방지 대규모 프로젝트에서의 최적화 작업

    💎 전역 상태 관리: Redux 노트 💎


    1️⃣ Redux 개념
    • Redux예측 가능한 상태 관리를 위한 자바스크립트 라이브러리로, React 애플리케이션의 전역 상태를 일관성 있게 관리할 수 있어.
    • 모든 상태는 하나의 store에서 관리되며, actionreducer를 통해 상태 변경이 이루어져.
    • React 외에도 Angular, Vue 등 다양한 프레임워크와 호환 가능해.
    🌟 Redux의 주요 구성 요소
    • 🏪 Store: 상태가 저장되는 공간
    • 🎬 Action: 상태에 일어날 변화를 설명하는 객체
    • 🛠️ Reducer: 액션에 따라 상태를 업데이트하는 함수
    • 🔗 Dispatch: 액션을 리듀서에 전달하는 함수

    2️⃣ Redux 사용 시기
    • 복잡한 상태 관리가 필요한 경우 (대규모 애플리케이션)
    • 🔗 다양한 컴포넌트 간의 상태 공유가 필요할 때
    • 🕹️ 일관성 있는 상태 업데이트가 중요할 때
    • 📦 디버깅 및 상태 추적이 필요한 프로젝트

    3️⃣ Redux 기본 사용법🏪 1. Store 생성🎬 2. 컴포넌트에서 상태 사용📝 예제 설명
    • store를 Provider로 감싸 전역 상태를 제공.
    • useSelector로 상태 접근, useDispatch로 액션 전달.

    4️⃣ Redux의 장단점
    • 일관성 있는 상태 관리: 단일 store를 통해 상태 추적 용이
    • 디버깅 편의성: Redux DevTools 지원
    • 예측 가능한 상태 흐름: 액션과 리듀서를 통한 명확한 상태 변경
    단점
    • ⚠️ 보일러플레이트 코드: 설정과 구성에 많은 코드 필요
    • ⚠️ 학습 곡선: 액션, 리듀서, 스토어 개념 이해 필요
    • ⚠️ 간단한 프로젝트에 과한 설정

    5️⃣ Redux 고급 사용법
    • 비동기 작업을 처리하기 위해 redux-thunk와 같은 미들웨어를 사용.
    💡 비동기 예제 코드
    // App.js
    import React, { useEffect } from 'react';
    import { Provider, useSelector, useDispatch } from 'react-redux';
    import { store, fetchData } from './store';
    
    const DataDisplay = () => {
      const data = useSelector((state) => state.data);
      const dispatch = useDispatch();
    
      useEffect(() => {
        dispatch(fetchData());
      }, [dispatch]);
    
      return (
        <div>
          <h2>📦 Data from API:</h2>
          <pre>{JSON.stringify(data, null, 2)}</pre>
        </div>
      );
    };
    
    const App = () => (
      <Provider store={store}>
        <DataDisplay />
      </Provider>
    );
    
    export default App;
    
    

    6️⃣ Redux 요약 정리
    🎨 핵심 기능 단일 store로 전역 상태 관리 카운터 앱, 사용자 인증 관리
    사용 시기 대규모 앱, 상태 공유 및 복잡한 상태 관리 필요 시 전자상거래 사이트, 대시보드
    🚀 미들웨어 사용 redux-thunk를 통한 비동기 상태 처리 API 데이터 페칭, 비동기 작업 처리
    💎 성능 최적화 리렌더링 최적화 및 불필요한 상태 업데이트 방지 대규모 프로젝트 최적화

    🚀 전역 상태 관리: Redux Toolkit 노트 🚀


    1️⃣ Redux Toolkit 개념


    • Redux Toolkit은 Redux의 공식 표준 툴킷으로, 복잡하고 반복적인 Redux 설정을 간소화해.
    • 기본적인 Redux 기능인 store, reducer, action을 간결하게 생성할 수 있어.
    • Redux DevTools와 기본 통합되어 디버깅이 용이해.
    🌟 Redux Toolkit의 주요 기능
    • configureStore: 간편한 스토어 설정
    • 🧩 createSlice: action과 reducer를 자동 생성
    • 🌐 createAsyncThunk: 비동기 작업 처리
    • 🔧 createReducer: 간결한 리듀서 생성

    2️⃣ Redux Toolkit 사용 시기
    • 🏃 빠른 Redux 설정이 필요한 경우
    • 💡 보일러플레이트 코드를 줄이고 싶을 때
    • 🚀 비동기 작업이 자주 발생하는 프로젝트에서
    • 🏗️ 대규모 상태 관리가 필요한 복잡한 애플리케이션

    3️⃣ Redux Toolkit 기본 사용법🏪 1. Slice 생성 및 스토어 설정🎬 2. 컴포넌트에서 상태 사용📝 예제 설명
    • createSlice를 사용하여 reducer와 action을 동시에 생성.
    • configureStore로 간단하게 store를 설정.
    • useSelector, useDispatch로 상태 접근 및 업데이트.

    4️⃣ Redux Toolkit 고급 사용법💡 비동기 예제 코드
    // App.js
    import React, { useEffect } from 'react';
    import { Provider, useSelector, useDispatch } from 'react-redux';
    import store, { fetchUser } from './userSlice';
    
    const UserProfile = () => {
      const { user, status } = useSelector((state) => state);
      const dispatch = useDispatch();
    
      useEffect(() => {
        dispatch(fetchUser());
      }, [dispatch]);
    
      return (
        <div>
          <h2>👤 User Profile</h2>
          {status === 'loading' ? <p>Loading...</p> : <pre>{JSON.stringify(user, null, 2)}</pre>}
        </div>
      );
    };
    
    const App = () => (
      <Provider store={store}>
        <UserProfile />
      </Provider>
    );
    
    export default App;
    
    📝 예제 설명
    • createAsyncThunk를 사용해 비동기 API 호출 처리.
    • extraReducers로 비동기 상태(loading, succeeded, failed) 관리.

    5️⃣ Redux Toolkit의 장단점
    • 간결한 코드: action과 reducer를 한 번에 생성
    • 비동기 작업 내장 지원: createAsyncThunk로 간단한 비동기 처리
    • DevTools 통합: 상태 추적 및 디버깅 용이
    • 권장 표준 방식: Redux 팀이 공식적으로 권장
    단점
    • ⚠️ 기본 Redux 개념 이해 필요
    • ⚠️ 간단한 앱에는 과도할 수 있음

    6️⃣ Redux Toolkit 요약 정리🔥
    🎨 핵심 기능 createSlice, configureStore로 간단한 상태 관리 카운터 앱, 사용자 인증 관리
    사용 시기 빠른 설정 및 간결한 Redux 사용이 필요할 때 대시보드, 전자상거래 앱
    🚀 비동기 작업 처리 createAsyncThunk를 사용한 비동기 상태 처리 API 호출, 데이터 페칭
    💎 성능 최적화 DevTools와의 통합, 상태 업데이트 최적화 대규모 애플리케이션 최적화