๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

React

[ React / Redux ] Redux ์ƒํƒœ ๊ด€๋ฆฌ ๊ฐœ๋…์ •๋ฆฌ.

 

๊ธฐ์กด์— ๋‚ด๊ฐ€ React ํ”„๋กœ์ ํŠธ์— ์ฆ๊ฒจ ์‚ฌ์šฉํ•˜๋˜ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” recoil ์ด์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ƒˆ๋กœ์šด ํšŒ์‚ฌ์—์„œ๋Š” Mobx์™€ Redux๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ Redux ๊ณต๋ถ€๋ฅผ ์œ„ํ•ด ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€๋ฅผ ๋ณด๋ฉฐ ๊ฐœ๋… ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

 

 


 

Redux ๊ธฐ๋ณธ ๊ฐœ๋…

 

Redux๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์•ฑ์„ ์œ„ํ•œ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์ƒํƒœ ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•œ๋‹ค.

์ผ๊ด€์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ณ  ์„œ๋กœ ๋‹ค๋ฅธ ํ™˜๊ฒฝ (์„œ๋ฒ„, ํด๋ผ์ด์–ธํŠธ, ๋„ค์ดํ‹ฐ๋ธŒ)์—์„œ ์ž‘๋™ํ•˜๊ณ , ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์‰ฌ์šด ์•ฑ์„ ๋งŒ๋“ค๋„๋ก ๋„์™€์ฃผ๋ฉฐ

Redux๋Š” React๋ฟ๋งŒ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋งค์šฐ ์ž‘์€ ์šฉ๋ž‘(์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํฌํ•จ 2KB)์œผ๋กœ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ๋“ค์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Redux๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ SPA์—์„œ ๊ฐ–์ถ”์–ด์•ผ ํ•  ์š”๊ฑด๋“ค์ด ์ ์  ๋ณต์žกํ•ด์ง์— ๋”ฐ๋ผ ๋งŽ์€ ์ƒํƒœ๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌ ํ•  ํ•„์š”์„ฑ๋•Œ๋ฌธ์— ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋˜์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

 

์—ฌ๊ธฐ์—์„œ ์ƒํƒœ๋ž€ ์„œ๋ฒ„์‘๋‹ต, ์บ์‹œ ๋ฐ์ดํ„ฐ, ์ง€์—ญ์ ์œผ๋กœ ์ƒ์„ฑ๋˜์–ด ์‚ฌ์šฉ์ค‘์ด์ง€๋งŒ ์„œ๋ฒ„์— ์ €์žฅ๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ,

์ด์™ธ์—๋„ ํ™œ์„ฑํ™”๋œ ๋ผ์šฐํŠธ, ์„ ํƒ๋œ ํƒญ, ๋กœ๋”ฉ์„ ๋ณด์—ฌ์ค„์ง€ ์—ฌ๋ถ€, ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ปจํŠธ๋กค ๋“ฑ์˜ ๋‹ค์–‘ํ•œ UI์ƒํƒœ๋„ ํฌํ•จ๋œ๋‹ค.

 

 

 

Redux์˜ ์„ธ๊ฐ€์ง€ ์›์น™

 

1. ์ง„์‹ค์€ ํ•˜๋‚˜์˜ ๊ทผ์›์œผ๋กœ๋ถ€ํ„ฐ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ์ƒํƒœ๋Š” ํ•˜๋‚˜์˜ ์ €์žฅ์†Œ ์•ˆ์— ํ•˜๋‚˜์˜ ๊ฐ์ฒด ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ์ €์žฅ๋œ๋‹ค.

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

console.log(store.getState())

/* Prints
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/

 

 

 

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

์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๋Š” ์ง€๋ฅผ ๋ฌ˜์‚ฌํ•˜๋Š” ์•ก์…˜ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋ฟ์ด๋‹ค.

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

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})

store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

 

 

 

 

3. ๋ณ€ํ™”๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑ๋˜์–ด์•ผ ํ•œ๋‹ค.

์•ก์…˜์— ์˜ํ•ด ์ƒํƒœ ํŠธ๋ฆฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€ํ™”ํ•˜๋Š” ์ง€๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์ˆœ์ˆ˜ ๋ฆฌ๋“€์„œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

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

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
const reducer = combineReducers({ visibilityFilter, todos })
const store = createStore(reducer)

 

 

 

 

 

Redux ์šฉ์–ด

 

- ์ƒํƒœ(State)

type State = any

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

 

 

 

- ์•ก์…˜(Action)

type Action = Object

์•ก์…˜์€ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋ ค๋Š” ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๊ฐ์ฒด๋กœ, ์ €์žฅ์†Œ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค. UI์ด๋ฒคํŠธ์—์„œ ์˜ค๊ฑฐ๋‚˜, ๋„คํŠธ์›Œํฌ ์ฝœ๋ฐฑ์—์„œ ์™”๊ฑฐ๋‚˜, ์›น์†Œ์ผ“๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ์†Œ์Šค์—์„œ ์™”๊ฑฐ๋‚˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋Š” ์•ก์…˜์„ ํ†ตํ•ด ๋ณด๋‚ด์ง„๋‹ค.

 

์•ก์…˜์€ ์–ด๋–ค ํ˜•ํƒœ์˜ ์•ก์…˜์ด ํ–‰ํ•ด์งˆ์ง€ ํ‘œ์‹œํ•˜๋Š” type ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ์•ผํ•˜๋ฉฐ, ํƒ€์ž…์€ ์ƒ์ˆ˜๋กœ ์ •์˜๋˜๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ž„ํฌํŠธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฌธ์ž์—ด์€ ์ง๋ ฌํ™”๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž…์œผ๋กœ Symbol๋ณด๋‹ค๋Š” ๋ฌธ์ž์—ด์„ ์“ฐ๋Š”๊ฒŒ ์ข‹๋‹ค.

 

์•ก์…˜ ๊ฒฉ์ฒด์—์„œ type์™ธ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์€ ์‚ฌ์šฉ์ž ๋งˆ์Œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. Flux Standard Action์—์„œ ์•ก์…˜์ด ์–ด๋–ป๊ฒŒ ๊ตฌ์ƒ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ๊ถŒ์žฅ์‚ฌํ•ญ์„ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

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

type Reducer<S, A> = (state: S, action: A) => S

๋ฆฌ๋“€์„œ(๋ฆฌ๋“€์‹ฑ ํ•จ์ˆ˜๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•จ.)๋Š” ๋ˆ„์ ๊ฐ’๊ณผ ๊ฐ’์„ ๋ฐ›์•„์„œ ์ƒˆ๋กœ์šด ๋ˆ„์ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๊ฐ’๋“ค์˜ ์ปฌ๋ ‰์…˜์„ ๋ฐ›์•„์„œ ํ•˜๋‚˜์˜ ๊ฐ’์œผ๋กœ ์ค„์ด๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

 

๋ฆฌ๋“€์„œ๋Š” Redux๋งŒ์˜ ๊ฐœ๋…์€ ์•„๋‹ˆ๊ณ , ๊ธฐ๋ณธ ๊ฐœ๋…์€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์™”๋‹ค๊ณ  ํ•œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” Array.prototype.reduce() ๊ฐ€ ํ•ด๋‹น๋œ๋‹ค.

 

Redux์—์„œ ๋ˆ„์ ๊ฐ’์€ ์ƒํƒœ ๊ฐ์ฒด์ด๊ณ , ๋ˆ„์ ๋  ๊ฐ’์€ ์•ก์…˜์ด๋‹ค. ๋ฆฌ๋“€์„œ๋Š” ์ฃผ์–ด์ง„ ์ด์ „ ์ƒํƒœ์™€ ์•ก์…˜์—์„œ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. ๋ฆฌ๋“€์„œ๋Š” ๋ฐ˜๋“œ์‹œ ๊ฐ™์€ ์ž…๋ ฅ์ด ์žˆ์œผ๋ฉด ๊ฐ™์€ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜์—ฌ์•ผ๋งŒ ํ•˜๋ฉฐ, ๋ถ€์ˆ˜ํšจ๊ณผ๋ฅผ ๊ฐ€์ ธ์„œ๋Š” ์•ˆ๋œ๋‹ค. ๋ฆฌ๋“€์„œ๋Š” Redux์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋…์œผ๋กœ, API ํ˜ธ์ถœ์„ ๋ฆฌ๋“€์„œ ์•ˆ์— ๋„ฃ์ง€ ๋ง๋ผ๊ณ  ๊ฒฝ๊ณ ํ•œ๋‹ค.

 

 

 

- ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜(Dispatch)

type BaseDispatch = (a: Action) => Action
type Dispatch = (a: Action | AsyncAction) => any

๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜๋Š” ์•ก์…˜์ด๋‚˜ ๋น„๋™๊ธฐ ์•ก์…˜์„ ๋ฐ›๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๋ฐ›์€ ๋‹ค์Œ ํ•˜๋‚˜ ๋˜๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ์•ก์…˜์„ ์ €์žฅ์†Œ์— ๋ณด๋‚ด๊ฑฐ๋‚˜ ๋ณด๋‚ด์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค.

๋ณดํ†ต์˜ ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜์™€, ์ €์žฅ์†Œ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ dispatch ํ•จ์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•ด์•ผ ํ•œ๋‹ค.

 

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

 

๋ฏธ๋“ค์›จ์–ด๋Š” ๊ธฐ๋ณธ ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ผ๋‹ค. ๋ฏธ๋“ค์›จ์–ด๋ฅผ ํ†ตํ•ด ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜๋Š” ์•ก์…˜ ๋ฟ ์•„๋‹ˆ๋ผ ๋น„๋™๊ธฐ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฏธ๋“ค์›จ์–ด๋Š” ์•ก์…˜์ด๋‚˜ ๋น„๋™๊ธฐ ์•ก์…˜์„ ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด์— ๋„˜๊ธฐ๊ธฐ ์ „์— ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜, ์ง€์—ฐ์‹œํ‚ค๊ฑฐ๋‚˜, ๋ฌด์‹œํ•˜๊ฑฐ๋‚˜, ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

- ์•ก์…˜ ์ƒ์‚ฐ์ž(ActionCreator)

type ActionCreator<A, P extends any[] = any[]> = (...args: P) => Action | AsyncAction

์•ก์…˜ ์ƒ์‚ฐ์ž๋Š” ์•ก์…˜์„ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์•ก์…˜์€ ์ •๋ณด์˜ ๋ฌถ์Œ์ด๊ณ , ์•ก์…˜ ์ƒ์‚ฐ์ž๋Š” ์•ก์…˜์„ ๋งŒ๋“œ๋Š” ๊ณณ์ด๋ผ์„œ ๋‘ ์šฉ์–ด๋ฅผ ํ˜ผ๋™ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

 

์•ก์…˜ ์ƒ์‚ฐ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์•ก์…˜์„ ๋งŒ๋“ค์–ด๋‚ผ ๋ฟ ๋””์ŠคํŒจ์น˜ ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ์ €์žฅ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” dispatch ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

์•ก์…˜ ์ƒ์‚ฐ์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅ์†Œ ์ธ์Šคํ„ด์Šค๋กœ ๋ฐ”๋กœ ๋””์ŠคํŒจ์น˜ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ”์ธ๋“œ๋œ ์•ก์…˜ ์ƒ์‚ฐ์ž๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•œ๋‹ค.

 

์•ก์…˜ ์ƒ์‚ฐ์ž๊ฐ€ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ฝ์–ด์•ผ ํ•˜๊ฑฐ๋‚˜, API ํ˜ธ์ถœ์„ ์‹คํ–‰ํ•ด์•ผ ํ•˜๊ฑฐ๋‚˜, ๋ผ์šฐํŠธ ์ „ํ™˜๊ฐ™์€ ๋ถ€์ˆ˜ํšจ๊ณผ๋ฅผ ์ผ์œผ์ผœ์•ผ ํ•œ๋‹ค๋ฉด ์•ก์…˜ ๋Œ€์‹  ๋น„๋™๊ธฐ ์•ก์…˜์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

 

 

 

- ๋น„๋™๊ธฐ ์•ก์…˜(AsyncAction)

type AsyncAction = any

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

 

 

 

- ๋ฏธ๋“ค์›จ์–ด(Middleware)

type MiddlewareAPI = { dispatch: Dispatch, getState: () => State }
type Middleware = (api: MiddlewareAPI) => (next: Dispatch) => Dispatch

๋ฏธ๋“ค์›จ์–ด๋Š” ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜๋ฅผ ๊ฒฐํ•ฉํ•ด์„œ ์ƒˆ ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณ ์ฐจํ•จ์ˆ˜์ด๋‹ค. ๋ฏธ๋“ค์›จ์–ด๋Š” ์ข…์ข… ๋น„๋™๊ธฐ ์•ก์…˜์„ ์•ก์…˜์œผ๋กœ ์ „ํ™˜ํ•œ๋‹ค.

 

๋ฏธ๋“ค์›จ์–ด๋Š” ํ•จ์ˆ˜ ๊ฒฐํ•ฉ์„ ํ†ตํ•ด ์„œ๋กœ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์•ก์…˜์„ ๋กœ๊น…ํ•˜๊ฑฐ๋‚˜, ๋ผ์šฐํŒ…๊ณผ ๊ฐ™์€ ๋ถ€์ˆ˜ํšจ๊ณผ๋ฅผ ์ผ์œผํ‚ค๊ฑฐ๋‚˜, ๋น„๋™๊ธฐ API ํ˜ธ์ถœ์„ ๋™๊ธฐ ์•ก์…˜์œผ๋กœ ๋ฐ”๊พธ๋Š”๋ฐ ์œ ์šฉํ•˜๋‹ค. 

 

applyMiddleware(...middlewares)๋ฅผ ํ†ตํ•ด ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

- ์ €์žฅ์†Œ(Store)

type Store = {
  dispatch: Dispatch,
  getState: () => State,
  subscribe: (listener: () => void) => () => void,
  replaceReducer: (reducer: Reducer) => void
}

์ €์žฅ์†Œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ ํŠธ๋ฆฌ๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด์ด๋‹ค. ๋ฆฌ๋“€์„œ ์ˆ˜์ค€์—์„œ ๊ฒฐํ•ฉ์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— Redux ์•ฑ์—๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์ €์žฅ์†Œ๋งŒ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

  • dispatch(action)๋Š” ์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ธฐ๋ณธ ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜์ด๋‹ค.
  • getState()๋Š” ์ €์žฅ์†Œ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • subscribe(listener)๋Š” ์ƒํƒœ๊ฐ€ ๋ฐ”๋€” ๋•Œ ํ˜ธ์ถœ๋  ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.
  • replaceReducer(nextReducer)๋Š” ํ•ซ ๋ฆฌ๋กœ๋”ฉ๊ณผ ์ฝ”๋“œ ๋ถ„ํ• ์„ ๊ตฌํ˜„ํ• ๋•Œ ์‚ฌ์šฉ๋˜๋ฉฐ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•  ์ผ์€ ๋ณ„๋กœ ์—†๋‹ค.

์ €์žฅ์†Œ API ๋ ˆํผ๋Ÿฐ์Šค ์ฐธ๊ณ  

 

 

- ์ €์žฅ์†Œ ์ƒ์‚ฐ์ž(StoreCreator)

type StoreCreator = (reducer: Reducer, preloadedState: ?State) => Store

์ €์žฅ์†Œ ์ƒ์‚ฐ์ž๋Š” Redux ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๋””์ŠคํŒจ์น˜ ํ•จ์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ReduxํŒจํ‚ค์ง€์— ๋“ค์–ด์žˆ๋Š” ๊ธฐ๋ณธ ์ €์žฅ์†Œ ์ƒ์‚ฐ์ž์ธ creatorStore(reducer, preloadedState) ์™€ ์ €์žฅ์†Œ ์ธํ•ธ์„œ์— ๋ฐ˜ํ™˜๋˜๋Š” ์ €์žฅ์†Œ ์ƒ์‚ฐ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ด์•ผ ํ•œ๋‹ค.

 

 

 

- ์ €์žฅ์†Œ ์ธํ•ธ์„œ(StoreEnhancer)

type StoreEnhancer = (next: StoreCreator) => StoreCreator

์ €์žฅ์†Œ ์ธํ•ธ์„œ๋Š” ์ €์žฅ์†Œ ์ƒ์‚ฐ์ž๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ๊ฐ•ํ™”๋œ ์ƒˆ ์ €์žฅ์†Œ ์ƒ์‚ฐ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณ ์ฐจํ•จ์ˆ˜์ด๋‹ค. ๋ฏธ๋“ค์›จ์–ด์™€ ๋น„์Šทํ•˜๊ฒŒ ์กฐํ•ฉ ๊ฐ€๋Šฅํ•œ ๋ฐฉ์‹์œผ๋กœ ์ €์žฅ์†Œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

 

์ €์žฅ์†Œ ์ธํ•ธ์„œ๋Š” React์—์„œ "์ปดํฌ๋„ŒํŠธ ์ธํ•ธ์„œ"๋กœ ๋ถˆ๋ฆฌ๋Š” ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ์™€ ๊ฐ™์€ ๊ฐœ๋…์ด๋‹ค.

 

์ €์žฅ์†Œ๋Š” ์ธ์Šคํ„ด์Šค๋ผ๊ธฐ๋ณด๋‹ค ํ•จ์ˆ˜๋“ค์ด ๋ชจ์ธ ์ผ๋ฐ˜์ ์ธ ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด์˜ ์ €์žฅ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ๋ณต์ œ๋ณธ์„ ๋งŒ๋“ค๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

compose ๋ฌธ์„œ ์˜ˆ์ œ ์ฐธ๊ณ .

 

 

 


 ์ถœ์ฒ˜ 

Redux ๊ณต์‹ ํŽ˜์ด์ง€