๊ด€๋ฆฌ ๋ฉ”๋‰ด

sliver__

[React] Context + useReducer ๋ณธ๋ฌธ

Frontend/React

[React] Context + useReducer

sliver__ 2025. 4. 6. 18:53
728x90

๐Ÿง  React์˜ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ Context + useReducer๋กœ ์‰ฝ๊ฒŒ ํ•ด๋ณด์ž!

React๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด, ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ์ƒํƒœ ๊ณต์œ ๊ฐ€ ํ•„์š”ํ•ด์ง€๋Š” ์ˆœ๊ฐ„์ด ์ฐพ์•„์˜ต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ ํ”ํžˆ props drilling ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ฃ . ์ƒํƒœ๋ฅผ ์ž์‹์˜ ์ž์‹๊นŒ์ง€ ๊ณ„์† ๋„˜๊ฒจ์ค˜์•ผ ํ•˜๋‹ˆ๊นŒ์š”.

๊ทธ๋Ÿด ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ Context API์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Context๋งŒ์œผ๋กœ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•˜๊ณ  ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์ง€๊ธฐ๋„ ํ•ด์š”. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด useReducer๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์•„์ฃผ ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ Context API + useReducer ์กฐํ•ฉ์ด๋ž€?

Context API๋Š” ์ „์—ญ ์ƒํƒœ๋ฅผ ๋งŒ๋“ค๊ณ  ์•ฑ ์ „์ฒด์— ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
useReducer๋Š” ๋ณต์žกํ•œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ switch-case ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

โœ… Context API๋Š” ์ „์—ญ ์ƒํƒœ ๊ณต๊ฐ„์„ ๋งŒ๋“œ๋Š” ์—ญํ• 
โœ… useReducer๋Š” ๊ทธ ๊ณต๊ฐ„์˜ ์ƒํƒœ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐ”๊ฟ€์ง€ ์ •์˜ํ•˜๋Š” ๋กœ์ง

๐Ÿ“ฆ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ์˜ˆ์‹œ

src/
โ”œโ”€โ”€ context/
โ”‚   โ””โ”€โ”€ CounterContext.js
โ”œโ”€โ”€ components/
โ”‚   โ””โ”€โ”€ Counter.js
โ”œโ”€โ”€ App.js

๐Ÿ”ง Step 1: Context + Reducer ์ •์˜


// src/context/CounterContext.js
import React, { createContext, useReducer, useContext } from 'react';

const initialState = { count: 0 };

const counterReducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    case 'RESET':
      return { count: 0 };
    default:
      throw new Error(`Unhandled action type: ${action.type}`);
  }
};

const CounterContext = createContext();

export const CounterProvider = ({ children }) => {
  const [state, dispatch] = useReducer(counterReducer, initialState);

  return (
    
      {children}
    
  );
};

export const useCounter = () => {
  const context = useContext(CounterContext);
  if (!context) {
    throw new Error('useCounter must be used within a CounterProvider');
  }
  return context;
};

๐Ÿงฑ Step 2: Provider๋กœ ์•ฑ ๊ฐ์‹ธ๊ธฐ


// App.js
import React from 'react';
import { CounterProvider } from './context/CounterContext';
import Counter from './components/Counter';

function App() {
  return (

Context + useReducer Example


    
  );
}

export default App;

๐Ÿ”„ Step 3: ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ


// src/components/Counter.js
import React from 'react';
import { useCounter } from '../context/CounterContext';

const Counter = () => {
  const { state, dispatch } = useCounter();

  return (

Count: {state.count}


  );
};

export default Counter;

โœ… ์žฅ์  ์š”์•ฝ

์žฅ์  ์„ค๋ช…
๊ฐ€๋ณ๊ณ  ๋น ๋ฆ„ ๋ณ„๋„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด React๋งŒ์œผ๋กœ ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ
๊ฐ€๋…์„ฑ ์ƒํƒœ ๋กœ์ง์ด reducer์— ๋ชจ์—ฌ ์žˆ์–ด ๊ด€๋ฆฌ๊ฐ€ ์‰ฌ์›€
๋ชจ๋“ˆํ™” ์‰ฌ์›€ Context ๋‹จ์œ„๋กœ ์ž˜๊ฒŒ ์ชผ๊ฐœ์„œ ๊ธฐ๋Šฅ๋ณ„ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ
ํ…Œ์ŠคํŠธ ์šฉ์ด reducer ํ•จ์ˆ˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ผ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ„๋‹จํ•จ

โš ๏ธ ์ฃผ์˜ํ•  ์ 

  • ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋  ์ˆ˜ ์žˆ์Œ
    Context ๊ฐ’์„ ๊ตฌ๋…ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” Provider ๊ฐ’์ด ๋ฐ”๋€Œ๋ฉด ๋ฌด์กฐ๊ฑด ๋ฆฌ๋ Œ๋”๋ฉ๋‹ˆ๋‹ค.
    ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•: Context๋ฅผ ์ชผ๊ฐœ๊ฑฐ๋‚˜ useMemo, useContextSelector ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์–ด์š”.
  • ๋น„๋™๊ธฐ ๋กœ์ง์€ ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ
    Redux์ฒ˜๋Ÿผ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋น„๋™๊ธฐ ๋กœ์ง์€ useEffect ๋˜๋Š” ์ปค์Šคํ…€ ํ›…์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿงฉ ๋งˆ๋ฌด๋ฆฌ

Context + useReducer๋Š” React์—์„œ ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ฐ„๊ฒฐํ•˜๋ฉด์„œ๋„ ๊ฐ•๋ ฅํ•œ ์กฐํ•ฉ์ž…๋‹ˆ๋‹ค.
Redux๋ฅผ ๋„์ž…ํ•˜๊ธฐ์—” ๋ฌด๊ฑฐ์šด ๊ฒฝ์šฐ, ์ด ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๋‹จ์ˆœํ•˜๊ณ  ์ง๊ด€์ ์ธ ์ฝ”๋“œ๋กœ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

๐Ÿ‘‰ ์ค‘์†Œํ˜• ํ”„๋กœ์ ํŠธ, ๊ฐ„๋‹จํ•œ ์ƒํƒœ ๊ณต์œ ๊ฐ€ ํ•„์š”ํ•œ ์•ฑ์—์„œ ์•„์ฃผ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ž์œผ๋กœ ์ƒํƒœ๊ฐ€ ์ ์  ๋ณต์žกํ•ด์ง€๊ฑฐ๋‚˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์š”๊ตฌ๊ฐ€ ๋งŽ์•„์ง„๋‹ค๋ฉด, Redux์™€ ๊ฐ™์€ ์ „๋ฌธ ์ƒํƒœ ๊ด€๋ฆฌ ํˆด๋กœ์˜ ์ „ํ™˜๋„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.
ํ•˜์ง€๋งŒ ๊ทธ ์ „๊นŒ์ง€๋Š” Context + useReducer ์กฐํ•ฉ์ด๋ฉด ์ถฉ๋ถ„ํžˆ ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค ๐Ÿ’ช

728x90

'Frontend > React' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[React] useCallback  (0) 2025.04.11
[React] useEffect  (0) 2025.04.11
[React] Context API + useReducer  (0) 2025.04.06
[React] useRef props (react 18 vs 19)  (0) 2025.02.16
[React] useRef  (0) 2025.02.16
Comments