[React] useReducer

๊ฒจ๋ ˆยท2024๋…„ 12์›” 2์ผ

๐Ÿ“ useReducer
useState()์™€ ๊ฐ™์€ ์ƒํƒœ ๊ด€๋ฆฌ, ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ›…(Hook)์ด๋‹ค.

const [state, dispatch] = useReducer(reducer, initialState); 
  • state : ์ƒํƒœ ์ด๋ฆ„ (์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ƒํƒœ)
  • dispatch :ย ์ƒํƒœ(state) ๋ณ€๊ฒฝ ์‹œ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๋Š” ํ•จ์ˆ˜
  • reducer :ย dispatch๋ฅผ ํ™•์ธํ•ด์„œ state๋ฅผ ๋ณ€๊ฒฝํ•ด ์ฃผ๋Š” ํ•จ์ˆ˜
  • initialState :ย state์— ์ „๋‹ฌํ•  ์ดˆ๊ธฐ ๊ฐ’์œผ๋กœ ๊ฐ์ฒด, ๋ฐฐ์—ด ๋“ฑ ๋‹ค์–‘ํ•œ ๊ฐ’์œผ๋กœ ์ „๋‹ฌ ๊ฐ€๋Šฅ
  • ์–ธ์ œ ์‚ฌ์šฉํ• ๊นŒ?
    • ๋ณ€๊ฒฝํ•  ๊ฐ’์ด ๋งŽ์„ ๋•Œ(์ƒํƒœ ์—…๋ฐ์ดํŠธ) ์ฆ‰, ์ƒํƒœ ๊ด€๋ฆฌํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ ๋•Œ
    • ๊ตฌ์กฐํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์‹ถ์„ ๋•Œ

๊ทธ๋Ÿฐ๋ฐ ์„œ์น˜๋ฅผ ์ข€ ํ•ด๋ณด๋‹ˆ useReducer๋Š” React๋งŒ์„ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๋Š” ์ ๊ณ , Redux๋ฅผ ์ด์šฉํ•œ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

(+) ๊ทธ ์ด์œ ๊ฐ€ ๋ฆฌ๋•์Šค๊ฐ€ ์ถ”๊ตฌํ•˜๋Š” ๋ฐฉํ–ฅ, ์‚ฌ์šฉ๋ฒ•์ด ๋น„์Šทํ•ด์„œ ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์˜๊ฒฌ๋„ ์žˆ์—ˆ๋‹ค.


useReducer ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

https://ccomccomhan.tistory.com/281 ์—์„œ ์ดํ•ดํ•˜๊ธฐ ์ž˜ ์„ค๋ช…ํ•ด๋‘ฌ์„œ ์ฐธ๊ณ ํ•ด์„œ ์ž‘์„ฑํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค!

const [state, dispatch] = useReducer(reducer, initialState);

โœ” state ๐Ÿ‘‰ ๋นต ์žฌ๋ฃŒ ๋‹ด๋Š” ์ ‘์‹œ
: ์ƒํƒœ ์ด๋ฆ„ (์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ƒํƒœ)

โœ” dispatch ๐Ÿ‘‰ ์ฃผ๋ฌธ์„œ
: ์ƒํƒœ(state)๋ฅผ ๋ณ€๊ฒฝ ์‹œ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๋Š” 'ํ•จ์ˆ˜'

โœ” reducer ๐Ÿ‘‰ ์ œ์ž‘
: dispatch๋ฅผ ํ™•์ธํ•ด์„œ state๋ฅผ ๋ณ€๊ฒฝํ•ด ์ฃผ๋Š” 'ํ•จ์ˆ˜'

โœ” initialState ๐Ÿ‘‰ ๋นต ์žฌ๋ฃŒ
: state์— ์ „๋‹ฌํ•  ์ดˆ๊ธฐ ๊ฐ’


  • ๋น„์œ  ์„ค๋ช…
const [state, dispatch] = useReducer(reducer, 3);

๐Ÿ™‹ ๋นต ์ œ์ž‘ ์š”์ฒญ์ž
: "๋นต ์žฌ๋ฃŒ๋ฅผย ์ฒ˜์Œ์—๋Š”ย 3๊ฐœ๋กœ ํ•ด์•ผ์ง€~ย (initialState)"ย โ‡’ "๋‹ค ๊ณจ๋ž์œผ๋‹ˆ ์ ‘์‹œ์— ๋„ฃ์–ด์•ผ๊ฒ ๋‹ค!(state)"ย 

๐Ÿ‘จโ€๐Ÿณ๐Ÿณย ์ฃผ๋ฐฉ์žฅ
:ย "๋‹ค๋“ค ์ฃผ๋ชฉ! ์šฐ๋ฆฌ ์ฃผ๋ฐฉ์€ ์ •ํ•ด์ง„ ์ฃผ๋ฌธ์„œ(dispatch)๋Œ€๋กœ๋งŒ ์ œ์ž‘(reducer)ํ•œ๋‹ค! ์•Œ๊ฒ ๋‚˜?"

๐Ÿง‘๐Ÿง‘๐Ÿปโ€๐Ÿณย ์ฃผ๋ฐฉ์›๋“ค
: "๋„ต!"ย 



๊ทธ๋Ÿฐ๋ฐ dispatch, reducer๋Š” ๋‚ด๊ฐ€ ๋งŒ๋“ ์ ์ด ์—†๋Š”๋ฐ ๋ญ˜๊นŒ?

๐Ÿ‘จ๐Ÿปโ€๐Ÿณ๐Ÿณ reducer( )์™€ action

  • reducer( )๋Š” 2๊ฐ€์ง€ ์ธ์ž๋ฅผ ๋ฐ›์Œ.
    • state
      ์œ„์—์„œ ์„ ์–ธํ•œ state๊ฐ’์ด ๋“ค์–ด๊ฐ„๋‹ค. (์ดˆ๊ธฐ ๊ฐ’์€ ๋‹น์—ฐํžˆ initialState์—์„œ ์„ค์ •ํ•œ ๊ฐ’)
    • action
      ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด. ์ฆ‰, ์œ„์—์„œ ์„ ์–ธํ•œ dispatch(์ฃผ๋ฌธ์„œ)
  • ๋น„์œ  ์˜ˆ์‹œ
function reducer(state, action) {
	switch (action.type) {
    	case 'PLUS':
        	return state + 1;
        case 'MINUS': 
        	return state - 1;
        default: return state; 
   }
}

๐Ÿ‘จโ€๐Ÿณ๐Ÿณย ์ฃผ๋ฐฉ์žฅ
:ย "์šฐ๋ฆฌ ์ฃผ๋ฐฉ์€ ์ฃผ๋ฌธ์„œ(dispatch) ์† ์ฃผ๋ฌธ๋‚ด์—ญ์ด 'PLUS'๋ผ๋ฉด ์–ด๋– ํ•œ ์žฌ๋ฃŒ(state)๊ฐ€ ์˜ค๋”๋ผ๋„ ๋ฌด์กฐ๊ฑด + 1ํ•ด ์•Œ๊ฒ ์–ด!?"

๐Ÿง‘๐Ÿง‘๐Ÿปโ€๐Ÿณย ์ฃผ๋ฐฉ์›๋“ค
: "๋„ต!"ย 

๐Ÿ‘จโ€๐Ÿณ๐Ÿณย ์ฃผ๋ฐฉ์žฅ
:ย "์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ ์–ด๋†“์€ ์ œ์กฐ ๋ฐฉ์‹(reducer)์ด๋‹ˆ ์ ์–ด๋†“์€ ๋Œ€๋กœ๋งŒ ์‹คํ–‰ํ•˜๋ž€ ๋ง์ด์•ผ!ย ์•Œ๊ฒ ์–ด!?"


๐Ÿ“ action๊ฐ์ฒด (dispatch)
action๊ฐ์ฒด dispatch๋Š” ์œ„ ๋น„์œ  ์˜ˆ์ œ๋กœ ์„ค๋ช…ํ•˜์ž๋ฉด, '๋นต ์ฃผ๋ฌธ์ž๊ฐ€ ์ฃผ๋ฐฉ์— ์ „๋‹ฌํ• ย ์ฃผ๋ฌธ์„œ'๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • reducer( )์— ์ ์–ด๋†จ๋˜ type์„(์ฃผ๋ฌธ ๋ช…๋ น์–ด) ์ ๋Š”๋‹ค.
  • reducer์—์„œ ํ•„์š”ํ•  ๋ฐ์ดํ„ฐ, ๋ฐ์ดํ„ฐ ๊ฐ’(๋นต ์žฌ๋ฃŒ๋“ค)๋„ ๊ฐ™์ด ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•„์ˆ˜ ๊ทœ์น™์€ ์•„๋‹ˆ๋‚˜ ์•”๋ฌต์  ๊ตญ๋ฃฐ๋กœ 'type ์† ์•ก์…˜(๊ฐ’)์€ ๋Œ€๋ฌธ์ž์™€ '_'๋กœ ๊ตฌ์„ฑํ•œ๋‹ค.
// 1์„ ๋”ํ•˜๋Š” ์•ก์…˜(์ฃผ๋ฌธ ๋ช…๋ น)
{
 type: 'PLUS'
}
// 1์„ ๋นผ๋Š” ์•ก์…˜(์ฃผ๋ฌธ ๋ช…๋ น)
{
 type: 'MINUS'
}
// input ๊ฐ’์„(๋นต ์† ์žฌ๋ฃŒ ๋“ฑ) ๋ณ€๊ฒฝํ•˜๋Š” ์•ก์…˜(์ฃผ๋ฌธ ๋ช…๋ น)
{
 type: 'CHANGE_INGREDIENT',
 ingredient : 'corn',
 price : 3000
}
// ์ƒˆ๋กœ์šด ๊ฐ์ฒด(๋นต)๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์•ก์…˜ (์ฃผ๋ฌธ ๋ช…๋ น)
{
 type: 'CREATE_BREAD',
 bread: {
   name: 'corn_bread',
   price: 4500
 },
 ingredient: {
   name: 'corn',
   value: '300g'
 }
}

  • ๋น„์œ  ์˜ˆ์ œ
    dispatch๋Š” state๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๋ช…๋ น์–ด์™€ ์ •๋ณด๋“ค์„ ์„ธํŒ…ํ•˜๋Š” ๊ณณ์œผ๋กœ ๋ณดํ†ต ์•„๋ž˜์ฒ˜๋Ÿผ 2๊ฐ€์ง€ ํ˜•์‹์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.
// 1๋ฒˆ์งธ ๋ฐฉ๋ฒ•
const onPlus = () => {
   dispatch({type : 'PLUS'})
}

<button onClick={onPlus}>Plus</button>

/// 2๋ฒˆ์งธ ๋ฐฉ๋ฒ•
<button onClick={() => dispatch({ type: 'PLUS' })}>Plus</button>

๐Ÿ™‹ ๋นต ์ œ์ž‘ ์š”์ฒญ์ž
: "์ฃผ๋ฐฉ์žฅ๋‹˜! ์—ฌ๊ธฐ 'PLUS' 1ํšŒ ์š”์ฒญ์ด์š”!"ย 


  • ๋น„์œ  ์˜ˆ์ œ
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'PLUS':
      return state + 1;
    case 'MINUS':
      return state - 1;
    default:
      return state;
  }
}

function Baking() {
  // 3์„ value ์ €์žฅ
  // ์œ„์— ์„ ์–ธํ–ˆ๋˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” reducer ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์ฃผ๊ธฐ!
  // reducer์† ๋กœ์ง๋“ค์„ ์‹คํ–‰์‹œํ‚ฌ ๋ช…๋ น์–ด๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š” dispatch ์„ ์–ธ
  const [value, dispatch] = useReducer(reducer, 3);

  const onPlus = () => {
    dispatch({ type: 'PLUS' });
  };

  const onMinus = () => {
    dispatch({ type: 'MINUS' });
  };

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onPlus}>+1</button>
      <button onClick={onMinus}>-1</button>
    </div>
  );
}

export default Baking;

โœ… ํ๋ฆ„
: ์ดˆ๊ธฐ ๋žœ๋”๋ง ->ย  useReducer() ์„ ์–ธ -> '+1' ๋ฒ„ํŠผ ํด๋ฆญ

๐Ÿ‘จโ€๐Ÿณ๐Ÿณย ์ฃผ๋ฐฉ์žฅ
: ย "๋‹ค๋“ค ์ฃผ๋ชฉ! ์šฐ๋ฆฌ ์ฃผ๋ฐฉ์€ ์ •ํ•ด์ง„ ์ฃผ๋ฌธ์„œ(dispatch)๋Œ€๋กœ๋งŒ ์ œ์ž‘(reducer)ํ•œ๋‹ค! ์•Œ๊ฒ ๋‚˜?"
๐Ÿง‘๐Ÿง‘๐Ÿปโ€๐Ÿณย ์ฃผ๋ฐฉ์›๋“ค
: "๋„ต!"

ย 
๐Ÿ‘จโ€๐Ÿณ๐Ÿณย ์ฃผ๋ฐฉ์žฅย 
:ย "PLUS ์š”์ฒญ์ด ์˜ค๋ฉด ์žฌ๋ฃŒ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•˜๋ผ๊ณ ?"
๐Ÿง‘๐Ÿง‘๐Ÿปโ€๐Ÿณย ์ฃผ๋ฐฉ์›๋“คย 
: "ํ˜„์žฌ ์žฌ๋ฃŒ ์ƒํƒœ(number)์—์„œ +1 ํ•ฉ๋‹ˆ๋‹ค!"

๐Ÿ™‹ย ๋นต ์ œ์ž‘ ์š”์ฒญ์žย 
: "๋นต ์žฌ๋ฃŒ๋ฅผย ์ฒ˜์Œ์—๋Š”ย 3๊ฐœ๋กœ ํ•ด์•ผ์ง€~ย (initialState)"ย โ‡’ "๋‹ค ๊ณจ๋ž์œผ๋‹ˆ ์ ‘์‹œ์— ๋„ฃ์–ด์•ผ๊ฒ ๋‹ค!(state)"ย โ‡’ '+1' ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ "PLUS" ์ฃผ๋ฌธ ์š”์ฒญ์„ ํ†ตํ•ด์„œ ๋ฐ€๊ฐ€๋ฃจ๋ฅผ 4๊ฐœ๋กœ ๋งŒ๋“ค์–ด๋‹ฌ๋ผ๊ณ  ํ•ด์•ผ๊ฒ ๋‹ค!ย 

( [+1] ๋ฒ„ํŠผ ํด๋ฆญ)

๐Ÿ‘จโ€๐Ÿณ๐Ÿณย ์ฃผ๋ฐฉ์žฅย 
:ย "๋‹ค๋“ค ์ฃผ๋ชฉ! ๋ฐฉ๊ธˆ dispatch๋ฅผ ํ†ตํ•ด์„œ action์„ ์ทจํ•ด๋‹ฌ๋ผ๊ณ  ์š”์ฒญ์ด ์™”์–ด ์—ฌ๊ธฐ ์†๋‹˜์€.. ์–ด๋”” ๋ณด์ž~ type์€ 'PLUS'๋„ค? ๊ทธ๋ฆฌ๊ณ  ๋ฐ€๊ฐ€๋ฃจ๋ฅผ 3๊ฐœ๋ฅผ ๊ฐ™์ด ๋ณด๋‚ด์ฃผ์—ˆ๋„ค..? ์—ํ—ค์ด ์ด์ „ ์†๋‹˜์€ ์˜ฅ์ˆ˜์ˆ˜์—ฌ์„œ ํŽธํ–ˆ๋Š”๋ฐ.. ์•„๋ฌดํŠผ ์šฐ๋ฆฌ๋Š” PLUS ์š”์ฒญ์ด ์˜ค๋ฉด ์žฌ๋ฃŒ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•˜๋ผ๊ณ ?'

๐Ÿง‘๐Ÿง‘๐Ÿปโ€๐Ÿณย ์ฃผ๋ฐฉ์›๋“คย 
:ย "๋„˜์–ด์˜จ ์žฌ๋ฃŒ๋ฅผ (number)ย +1 ํ•ฉ๋‹ˆ๋‹ค!"
๐Ÿ‘จโ€๐Ÿณ๐Ÿณย ์ฃผ๋ฐฉ์žฅย 
:ย "๋ญ ํ•ด ๋‹น์žฅ ์ง„ํ–‰์‹œ์ผœ!(reducer ์† case ์‹คํ–‰)

profile
ํ˜ธ๋–ก ์‹ ๋ฌธ์ง€์—์„œ ๊ฐœ๋ฐœ์ž๋กœ ํ™˜์ƒ

0๊ฐœ์˜ ๋Œ“๊ธ€