๐Ÿฆ„ Redux

์€์œ ๋กœ๊ทธยท2021๋…„ 11์›” 29์ผ
0

๐Ÿ“š study

๋ชฉ๋ก ๋ณด๊ธฐ
16/21
post-custom-banner

์ด์ „์— ๋ฆฌ๋•์Šค์— ๊ด€ํ•ด ์ •๋ฆฌํ•œ ์ ์ด ์žˆ๋‹ค. ๋„ˆ๋ฌด ๊ฐ„์†Œํ•˜๊ฒŒ ์ •๋ฆฌํ•ด์„œ ์ด๋ฒˆ์— ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ ์ „ ๊ณต๋ถ€ํ•  ๊ฒธ ๋‹ค์‹œ ์ •๋ฆฌํ•ด ๋ณธ๋‹ค.


๋ฆฌ๋•์Šค๋Š” ๋ญ”๋ฐ? ์จ์•ผํ•˜๋Š” ์ด์œ ๋Š”?

๋ฆฌ๋•์Šค๋Š” ๋ฆฌ์•กํŠธ๋กœ ๋งŒ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ƒํƒœ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋„๊ตฌ์ด๋‹ค. (๋ฌผ๋ก  ๋ฆฌ์•กํŠธ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ jQuery, Angular ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค!) ์ฒ˜์Œ ๋ฆฌ๋•์Šค๋ฅผ ๋ฐฐ์› ์„ ๋•Œ ์™œ ๋ฆฌ๋•์Šค๋ฅผ ๋ฐฐ์šฐ๊ณ , ์ ์šฉํ•ด์•ผํ•˜๋Š”์ง€ ๋ชฐ๋ž์ง€๋งŒ ์ฒซ๋ฒˆ์งธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์™œ ํ•„์š”ํ•˜๊ณ , ๋ฆฌ๋•์Šค๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ์ƒํƒœ๊ด€๋ฆฌ๊ฐ€ ํŽธ๋ฆฌํ•  ๊ฒƒ์ด๋ž€ ๊ฑธ ์ ˆ์‹คํžˆ ๊นจ๋‹ฌ์•˜๋‹ค.

๋ฆฌ์•กํŠธ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ContextAPI์™€ useReducer ํ›…์„ ์ด์šฉํ•ด ๋ฌผ๋ก  ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋งŒ์•ฝ ์ƒ์„ฑํ•ด์•ผ ํ•  ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•œ ๋‘๊ฐœ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด? ๊ทธ ์ž์‹์˜, ์ž์‹์˜, ์ž์‹์˜, ์ž์‹์˜, ... ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•ด์ค˜์•ผ ํ•œ๋‹ค๋ฉด? ๋งŒ์•ฝ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„๋‹Œ ์ € ๋ฉ€๋ฆฌ ์žˆ๋Š” ํ˜•์ œ ๊ด€๊ณ„์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์•„์•ผํ•œ๋‹ค๋ฉด? ์•„์ฃผ ์ง€์˜ฅ์„ ๋ง›๋ณผ๊ฒƒ์ด๋‹ค.. ใ…‹ใ…‹ใ…‹ ๐Ÿ˜ˆ

ํ‚ค์›Œ๋“œ & ํ๋ฆ„

์•ก์…˜(Action) + ์•ก์…˜ ์ƒ์„ฑํ•จ์ˆ˜ (Action Creator)

์ƒํƒœ์˜ ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•  ๋• ์•ก์…˜์ด๋ž€ ๊ฐ์ฒด๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. ์•ก์…˜ ๊ฐ์ฒด๋Š” type ํ•„๋“œ๋ฅผ ํ•„์ˆ˜์ ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ๊ทธ ์™ธ ๊ฐ’๋“ค์€ ์ž…๋ง›๋Œ€๋กœ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค. ์•ก์…˜ ์ƒ์„ฑํ•จ์ˆ˜๋Š” ๋ง๊ทธ๋Œ€๋กœ ์•ก์…˜์„ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜์ด๋ฉฐ ์•ก์…˜ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

export const action = (data) => ({
  type: "action_type",
  data //data: data(๋ฐ›์•„์˜จ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๊ฐ’์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค.)
});

๋ฆฌ๋“€์„œ (Reducer)

๋ฆฌ๋“€์„œ๋Š” ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์ผ์œผํ‚ค๋Š” ํ•จ์ˆ˜์ด๋‹ค. ํ˜„์žฌ ์ƒํƒœ์™€ ์ „๋‹ฌ ๋ฐ›์€ ์•ก์…˜ ๋‘๊ฐ€์ง€์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ณ  ๊ทธ ์•ก์…˜์„ ์ฐธ๊ณ ํ•ด์„œ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•œ๋‹ค. switch-case๋ฌธ์„ ์“ฐ๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๊ณ  default์—์„œ state๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฆฌ๋“€์„œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ  ์ด๋ฅผ ์ „๋ถ€ ๋‹ค ํ•ฉ์ณ ๋ฃจํŠธ ๋ฆฌํŠœ์„œ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

// ๋ฆฌ๋“€์„œ ์ƒ์„ฑ ์ฝ”๋“œ
function reducer(state, action){
	switch (action.type) {
      case "action1":
        return state + 1;
      case "action2":
        return state - 1;
      default:
        return state;
    }
}


// ๋ฃจํŠธ ๋ฆฌ๋“€์„œ๋กœ ํ•ฉ์น˜๋Š” ์ฝ”๋“œ
import { combineReducers } from 'redux';
import reducer1 from './reducer1';
import reducer2 from './reducer2';

const rootReducer = combineReducers({ reducer1, reducer2 });

์Šคํ† ์–ด (Store)

ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋‹น ํ•˜๋‚˜์˜ ์Šคํ† ์–ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ์ด ์Šคํ† ์–ด์—๋Š” state์™€ reducer, ๋ช‡๊ฐ€์ง€์˜ ๋‚ด์žฅ ํ•จ์ˆ˜๋“ค์ด ์žˆ๋‹ค.

๋””์ŠคํŒจ์น˜ (dispatch)

์Šคํ† ์–ด์˜ ๋‚ด์žฅ ํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์•ก์…˜์„ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋ฉฐ ์•ก์…˜์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•œ๋‹ค. (๊ฐ์ฒด๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•œ๋‹ค๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ์˜๋ฏธ์ด๋‹ค.) ๋””์ŠคํŒจ์น˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์Šคํ† ์–ด์—์„œ ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œ์ผœ ํ•ด๋‹น ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์ด ์žˆ๋‹ค๋ฉด ์•ก์…˜์„ ์ฐธ๊ณ ํ•ด ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

ํ๋ฆ„

๊ผญ ์ง€์ผœ์•ผํ•˜๋Š” ์•ฝ์†

1. ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํ•˜๋‚˜์˜ ์Šคํ† ์–ด๋งŒ ๊ฐ€์ ธ์•ผํ•œ๋‹ค.

ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์Šคํ† ์–ด๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ๊ถŒ์žฅ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค.

2. ์ƒํƒœ๋Š” ์ฝ๊ธฐ ์ „์šฉ์ด๋‹ค.

๋ฆฌ๋“€์„œ์—์„œ ์ƒํƒœ๋ฅผ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ์„ค๋ช…ํ–ˆ๋Š”๋ฐ, ๊ทธ ์ด์œ ๋Š” ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ž˜์•ผ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ†ตํ•ด ๋’ค๋กœ ๋Œ๋ฆด ์ˆ˜๋„ ์žˆ๊ณ  ๋‹ค์‹œ ์•ž์œผ๋กœ ๋Œ๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค.
์ƒํƒœ๊ฐ€ ๋ฐฐ์—ด์ด๋‹ค โžก๏ธ push() ์‚ฌ์šฉ ์ ˆ๋Œ€ ๊ธˆ์ง€! concat๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด์˜ ๋ฐฐ์—ด์€ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ๊ต์ฒดํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
์ƒํƒœ๊ฐ€ ๊ฐ์ฒด๋‹ค โžก๏ธ ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๋‚˜(...state, ) Object.assign๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ์กด์˜ ๊ฐ์ฒด๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

3. ๋ฆฌ๋“€์„œ๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜์—ฌ์•ผ ํ•œ๋‹ค.

๋ฆฌ๋“€์„œ๋Š” ์ด์ „ ์ƒํƒœ(PrevState)์™€ ์•ก์…˜ ๊ฐ์ฒด๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋Š”๋‹ค. ์ด์ „์˜ ์ƒํƒœ๋Š” ์ ˆ๋Œ€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ๋ณ€ํ™”๋ฅผ ์ผ์œผํ‚จ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•ด์•ผํ•œ๋‹ค. ๋˜‘๊ฐ™์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํ˜ธ์ถœ๋œ ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋Š” ์–ธ์ œ๋‚˜ ๋˜‘๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.


๋ฆฌ๋•์Šค ๋ฏธ๋“ค์›จ์–ด? ๊ทธ๊ฑด ๋˜ ๋ญ”๋ฐ?

๊ธฐ์กด์˜ ๋ฆฌ๋•์Šค๋Š” ์•ก์…˜์ด ๋ฐœ์ƒํ•˜๋ฉด ๋””์ŠคํŒจ์น˜๋ฅผ ํ†ตํ•ด ์Šคํ† ์–ด์—๊ฒŒ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์•Œ๋ ค์ค€๋‹ค. ๋งŒ์•ฝ ์–ด๋–ค ์•ก์…˜์ด ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๊ณ  ์‹ถ๋‹ค๊ฑฐ๋‚˜, ์•ก์…˜์„ ์ทจ์†Œํ•˜๊ณ ์‹ถ๊ฑฐ๋‚˜, ํ˜น์€ ๋˜ ๋‹ค๋ฅธ ์•ก์…˜์„ ์‹คํ–‰์‹œํ‚ค๊ณ  ์‹ถ์œผ๋ฉด? ๋™๊ธฐ์ ์ธ ๋ฆฌ๋•์Šค ํ๋ฆ„์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์‹คํ–‰ํ•ด์•ผํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฏธ๋“ค์›จ์–ด์ด๋‹ค.

  • ๋ฐฑ์—”๋“œ API ์—ฐ๋™์„ ํ•˜๊ณ ์‹ถ๋‹ค.
  • ์‹œ๊ฐ„์„ ๋”œ๋ ˆ์ด์‹œํ‚ค๊ณ  ์‹ถ๋‹ค.
  • ํŠน์ • ์•ก์…˜์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ด์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๋‹ค๋ฅธ ์•ก์…˜์„ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ์‹ถ๋‹ค.
  • ์•ก์…˜์ด ๋””์ŠคํŒจ์น˜ ๋์„ ๋•Œ ์ˆ˜์ •ํ•ด ๋ฆฌ๋“€์„œ์—๊ฒŒ ์ „๋‹ฌ๋˜๋ก ํ•˜๊ณ ์‹ถ๋‹ค...

๋“ฑ๋“ฑ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋ฆฌ๋•์Šค-๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๋ฆฌ๋•์Šค ๋ฏธ๋“ค์›จ์–ด์˜ ์ข…๋ฅ˜๋Š” redux-logger, redux-thunk, redux-saga, redux-observable, redux-promise-middleware ๋“ฑ์ด ์žˆ์ง€๋งŒ redux-logger, redux-thunk ๋ถ€๋ถ„๋งŒ ์ •๋ฆฌํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค.

๋ฆฌ๋•์Šค ๋ฏธ๋“ค์›จ์–ด ํ…œํ”Œ๋ฆฟ

const middleware = store => next => action => {
  console.log(action); // ์•ก์…˜์„ ์ถœ๋ ฅํ•œ๋‹ค.
  const result = next(action); // ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด(๋˜๋Š” ๋ฆฌ๋“€์„œ)์—๊ฒŒ ์•ก์…˜์„ ์ „๋‹ฌํ•œ๋‹ค.
  
  return result; // dispatch(action)์˜ ๊ฒฐ๊ณผ๋ฌผ - default: undefined
}

๋ฏธ๋“ค์›จ์–ด๋Š” ํ•จ์ˆ˜๋ฅผ ์—ฐ๋‹ฌ์•„์„œ ๋‘ ๋ฒˆ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ฒซ๋ฒˆ์งธ store๋Š” ๋ฆฌ๋•์Šค ์Šคํ† ์–ด ์ธ์Šคํ„ด์Šค์ด๋‹ค. ๋‘๋ฒˆ์งธ next๋Š” ์•ก์…˜์„ ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์„ธ๋ฒˆ์งธ action์€ ํ˜„์žฌ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์•ก์…˜ ๊ฐ์ฒด์ด๋‹ค.

redux-logger

import logger from 'redux-logger';

const store = createStore(rootReducer, applyMiddleware(logger));

๋ฆฌ๋•์Šค ๋กœ๊ฑฐ๋Š” ์•ฑ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์•ก์…˜ ์ •๋ณด๋ฅผ ์ฝ˜์†”์— ์ถœ๋ ฅํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด์ด๋‹ค. ๋””์ŠคํŒจ์น˜๋œ ์•ก์…˜์ด ์–ด๋–ค ์•ก์…˜์ธ์ง€ ํ™•์ธ ํ›„ ์ฝ˜์†”์— ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๊ณ  ์•ก์…˜์„ ์Šคํ† ์–ด์— ์ „๋‹ฌํ•œ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด logger๋Š” ๋ณดํ†ต ๋งจ ๋’ค์— ์“ฐ๋Š” ํŽธ์ด๋‹ค.

redux-thunk

๋ฆฌ๋•์Šค ํ……ํฌ๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด๋‹ค. ์•ก์…˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜๋ฅผ ๋””์ŠคํŒจ์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

const getComments = () => async (dispatch, getState) => {
  const id = getState().post.activeId;
  dispatch({ type: 'GET_COMMENTS' });
  try {
    const comments = await api.getComments(id);
    dispatch({ type:  'GET_COMMENTS_SUCCESS', id, comments });
  } catch (e) {
    dispatch({ type:  'GET_COMMENTS_ERROR', error: e });
  }
}

์˜ˆ์‹œ๋กœ ๊ฐ€์ ธ์˜จ ์ฝ”๋“œ๋ฅผ ํ•ด์„ํ•ด๋ณด๊ฒ ๋‹ค. getComments๋ผ๋Š” thunk ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•œ ์˜ˆ์‹œ์ด๋‹ค. thunk ํ•จ์ˆ˜๋Š” dispatch์™€ getState๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„์˜จ๋‹ค. id์— ํ˜„์žฌ ์ƒํƒœ์˜ post์—์„œ activeId ๊ฐ’์„ ํ• ๋‹นํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์š”์ฒญ์„ ์‹œ์ž‘ํ–ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” GET_COMMENTS ์•ก์…˜์„ ๋””์ŠคํŒจ์น˜์— ๋‹ด๋Š”๋‹ค. ๋งŒ์•ฝ ์š”์ฒญ์ด ์„ฑ๊ณตํ–ˆ๋‹ค๋ฉด comments payload๋ฅผ ๋‹ด๊ณ  ์š”์ฒญ์ด ์„ฑ๊ณตํ–ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” GET_COMMENTS_SUCCESS ์•ก์…˜์„ ๋””์ŠคํŒจ์น˜์— ๋‹ด์•„ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ด์ œ ๋ฆฌ๋“€์„œ๋ฅผ ํ†ตํ•ด ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ์žˆ์„ ๊ฒƒ์ด๋‹ค.

redux-thunk๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์‹ถ๋‹ค๋ฉด

import ReduxThunk from 'redux-thunk';

const store = createStore(
  rootReducer, applyMiddleware(ReduxThunk)
);

store๋ฅผ ์ •์˜ํ•ด๋‘” ๊ณณ์— applyMiddleware๋ฅผ ์“ฐ๊ณ  ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋‹ด์•„์ค€๋‹ค.

setTimeOut ํ™œ์šฉ ์˜ˆ์ œ

export const increase = () => ({ type: INCREASE });

// getState๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ตณ์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„์˜ฌ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค.
export const increaseAsync = () => dispatch => {
  setTimeout(() => dispatch(increase()), 1000);
};

์ฐธ๊ณ : ๋น›๊ฐ™์€ ๋ฒจ๋กœํผํŠธ ์Šจ์ƒ๋‹˜

profile
เน‘โ€ขโ€ฟโ€ขเน‘
post-custom-banner

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