Redux: ์ž‘์—…์ด ์—ฌ๋Ÿฌ ๊ฐ์†๊ธฐ์™€ ๊ด€๋ จ๋œ ๊ฒฝ์šฐ combineReducer์— ๋Œ€ํ•œ ์šฐ๋ ค

์— ๋งŒ๋“  2015๋…„ 08์›” 21์ผ  ยท  52์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: reduxjs/redux

์ €๋Š” React.js์™€ Flux๋กœ ๋นŒ๋“œ ๋œ ์ฑ„ํŒ… ์•ฑ ์„ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Redux์˜ ๋ฌธ์„œ๋ฅผ ์ฝ์„ ๋•Œ combineReducer ํ•จ์ˆ˜๊ฐ€ ์ด์ƒํ•˜๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด :

messageStore , unreadStore , threadStore ๋ผ๋Š” ์„ธ ๊ฐœ์˜ ์ƒ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  NEW_MESSAGE ๋ผ๋Š” ์•ก์…˜์ด โ€‹โ€‹์žˆ์Šต๋‹ˆ๋‹ค. ์„ธ ์ƒ์  ๋ชจ๋‘ ์ƒˆ ๋ฉ”์‹œ์ง€๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. Redux์—์„œ ์ €์žฅ์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด combineReducer ์™€ ๊ฒฐํ•ฉ ๋œ ๊ฐ์†๊ธฐ์ž…๋‹ˆ๋‹ค.

message = (state=[], action) ->
  switch action.type
    when NEW_MESSAGE
      state # new state
unread = (state=[], action) ->
  switch action.type
    when NEW_MESSAGE
      state # new state
thread = (state=[], action) ->
  switch action.type
    when NEW_MESSAGE
      state # new state

combineReducer {message, unread, thread}

๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ๋ฆฌ๋“€์„œ๋ฅผ ์ชผ๊ฐœ๋Š” ๊ฒƒ์ด ๋‚ด ์‚ถ์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ immutable-js๋กœ ๊ตฌ์ถ• ๋œ ๊ฑฐ๋Œ€ํ•œ ์ƒ์ ์ด์ด๋ฅผ์œ„ํ•œ ๋” ๋‚˜์€ ์†”๋ฃจ์…˜ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜๋Ÿผ:

initialState = Immutable.fromJS
  message: []
  unread: []
  thread: []

allStore = (store=initialState, action) ->
  switch action.type
    when NEW_MESSAGE
        initialState
        .updateIn ['message'], (messages) -> messages # updated
        .updateIn ['urnead'], (urneads) -> unreads # updated
        .updateIn ['thread'], (threads) -> threads # updated
question

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์œ„ํ•ด์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐ์†๊ธฐ (๋˜๋Š” ์•ฑ์ด ์ปค์ง„ ํ›„ ํŒŒ์ผ)์—์„œ ์œ ์ง€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋™์ผํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” 5 ๊ฐœ์˜ ์ƒ์ ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ์•ฝ๊ฐ„ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ๋„ˆ๋ฌด ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค์ด ์ข…์ข… ์ฐจ์„  ์ƒํƒœ ๋ชจ๋ธ์˜ ์ฆ์ƒ์ด๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด

์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ํ•œ ๋ฆฌ๋“€์„œ๊ฐ€ ๋‹ค๋ฅธ ๋ฆฌ๋“€์„œ์˜ ๋ฐ์ดํ„ฐ์— ์˜์กด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๋ฉ”์‹œ์ง€๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒˆ ์Šค๋ ˆ๋“œ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฉ”์‹œ์ง€์—์„œ ์Šค๋ ˆ๋“œ๋กœ ์Šน๊ฒฉํ•˜๋Š” ๋“ฑ).

๋ฌธ์ œ์˜ ์ฆ์ƒ์ž…๋‹ˆ๋‹ค. ์ƒํƒœ ๋‚ด์—์„œ ๋ฌผ๊ฑด์„ ๋งŽ์ด ์ด๋™ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์ƒํƒœ ๋ชจ์–‘์„ ๋” ํ‘œ์ค€ํ™”ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  { readMessages, unreadMessages } ๋‹น์‹ ์€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค { messagesById, threadsById, messageIdsByThreadIds } . ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์—ˆ์Šต๋‹ˆ๊นŒ? ์ข‹์Šต๋‹ˆ๋‹ค. state.messagesById[id].isRead ํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ณ  ์‹ถ์Šต๋‹ˆ๊นŒ? state.threadsById[threadId].messageIds ๋ฅผ ์„ ํƒํ•œ ๋‹ค์Œ messageIds.map(id => state.messagesById[id]) ํ•˜์„ธ์š”.

๋ฐ์ดํ„ฐ๊ฐ€ ์ •๊ทœํ™”๋˜๋ฉด ํ•œ ๋ฐฐ์—ด์—์„œ ๋‹ค๋ฅธ ๋ฐฐ์—ด๋กœ ํ•ญ๋ชฉ์„ ๋ณต์‚ฌ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํ”Œ๋ž˜๊ทธ๋ฅผ ๋’ค์ง‘๊ฑฐ๋‚˜ ID๋ฅผ ์ถ”๊ฐ€ / ์ œ๊ฑฐ / ์—ฐ๊ฒฐ / ์—ฐ๊ฒฐ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  52 ๋Œ“๊ธ€

์ด ๊ฒฝ์šฐ combineReducers ์ด ๋„์›€์ด๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๊ฐ™์€ ์ƒํƒœ์˜ ๊ฒฝ์šฐ ๋‹จ์ผ ๋ฆฌ๋“€์„œ (๊ทธ๋ฆฌ๊ณ  UI ์ƒํƒœ์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ๋ฆฌ๋“€์„œ (์˜ˆ : ์„ ํƒ๋œ ํ•ญ๋ชฉ ๋“ฑ))๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ๋ณด์‹ญ์‹œ์˜ค:

https://github.com/rackt/redux/tree/master/examples/real-world/reducers
https://github.com/rackt/redux/blob/master/examples/async/reducers

์˜๊ฐ์„ ์–ป๊ธฐ ์œ„ํ•ด.

๋‹น์‹ ์ด ์ง€์ ํ•œ ์ฒซ ๋ฒˆ์งธ ์˜ˆ๋Š” ๋‚ด ๊ฒฝ์šฐ์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. requestType ๋Š” ๋‘ ๊ฐ์†๊ธฐ์—์„œ ๋ชจ๋‘ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
https://github.com/rackt/redux/blob/master/examples/real-world/reducers/paginate.js#L28

๊ฐ์†๊ธฐ๋ฅผ ๋ถ„ํ• ํ•˜๋ฉด ๋‘ ๊ฐ์†๊ธฐ๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์†๊ธฐ์™€ ๋ถ„๋ฆฌ ๋  ๋•Œ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๋” ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋“ค์ด ๋™์ผํ•œ ํ–‰๋™์„ํ•˜๊ฒŒ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

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

์ด ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ €๋Š”์ด ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์™„์ „ํžˆ ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์œ„ํ•ด์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐ์†๊ธฐ (๋˜๋Š” ์•ฑ์ด ์ปค์ง„ ํ›„ ํŒŒ์ผ)์—์„œ ์œ ์ง€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋™์ผํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” 5 ๊ฐœ์˜ ์ƒ์ ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ์•ฝ๊ฐ„ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ๋„ˆ๋ฌด ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค์ด ์ข…์ข… ์ฐจ์„  ์ƒํƒœ ๋ชจ๋ธ์˜ ์ฆ์ƒ์ด๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด

์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ํ•œ ๋ฆฌ๋“€์„œ๊ฐ€ ๋‹ค๋ฅธ ๋ฆฌ๋“€์„œ์˜ ๋ฐ์ดํ„ฐ์— ์˜์กด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๋ฉ”์‹œ์ง€๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒˆ ์Šค๋ ˆ๋“œ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฉ”์‹œ์ง€์—์„œ ์Šค๋ ˆ๋“œ๋กœ ์Šน๊ฒฉํ•˜๋Š” ๋“ฑ).

๋ฌธ์ œ์˜ ์ฆ์ƒ์ž…๋‹ˆ๋‹ค. ์ƒํƒœ ๋‚ด์—์„œ ๋ฌผ๊ฑด์„ ๋งŽ์ด ์ด๋™ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์ƒํƒœ ๋ชจ์–‘์„ ๋” ํ‘œ์ค€ํ™”ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  { readMessages, unreadMessages } ๋‹น์‹ ์€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค { messagesById, threadsById, messageIdsByThreadIds } . ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์—ˆ์Šต๋‹ˆ๊นŒ? ์ข‹์Šต๋‹ˆ๋‹ค. state.messagesById[id].isRead ํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ณ  ์‹ถ์Šต๋‹ˆ๊นŒ? state.threadsById[threadId].messageIds ๋ฅผ ์„ ํƒํ•œ ๋‹ค์Œ messageIds.map(id => state.messagesById[id]) ํ•˜์„ธ์š”.

๋ฐ์ดํ„ฐ๊ฐ€ ์ •๊ทœํ™”๋˜๋ฉด ํ•œ ๋ฐฐ์—ด์—์„œ ๋‹ค๋ฅธ ๋ฐฐ์—ด๋กœ ํ•ญ๋ชฉ์„ ๋ณต์‚ฌ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํ”Œ๋ž˜๊ทธ๋ฅผ ๋’ค์ง‘๊ฑฐ๋‚˜ ID๋ฅผ ์ถ”๊ฐ€ / ์ œ๊ฑฐ / ์—ฐ๊ฒฐ / ์—ฐ๊ฒฐ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

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

@jiyinyiyong ๋‹น์‹ ์ด ๋งํ•˜๋Š” ๋ณต์žก์„ฑ์ด ๋ฌด์—‡์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ combineReducers ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„๋ฉ๋‹ˆ๋‹ค. ๋„์šฐ๋ฏธ ์ผ๋ฟ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹  Immutable์„ ์‚ฌ์šฉํ•˜๋Š” ์œ ์‚ฌํ•œ ๋„์šฐ๋ฏธ๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๋ฌผ๋ก  ์ž์‹  ๋งŒ์˜ ๊ธ€์„ ์“ฐ์„ธ์š”.

๋‚˜๋Š” ์ฃผ๋กœ Immutable.js๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด combineReducers() ๋„์šฐ๋ฏธ๋ฅผ ์ž‘์„ฑํ–ˆ์ง€๋งŒ ๋ฃจํŠธ ๊ฐ์†๊ธฐ์ฒ˜๋Ÿผ ์ทจ๊ธ‰๋˜๋Š” ์ถ”๊ฐ€ ๊ฐ์†๊ธฐ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/jokeyrhyme/wow-healer-bootcamp/blob/master/utils/combineReducers.js

์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์ƒํƒœ์˜ ๋ชจ์–‘๊ณผ ์ผ์น˜ํ•˜๊ณ  ์ตœ์ƒ์œ„ ํ•˜์œ„ ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ผ์น˜ํ•˜๋Š” ํ•˜์œ„ ๊ฐ์†Œ๊ธฐ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ณต์‹ ๋ฒ„์ „๊ณผ ๊ฑฐ์˜ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ 0 ๊ฐœ ์ด์ƒ์˜ ์ถ”๊ฐ€ ์ธ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉฐ ๋‹ค๋ฅธ ๋ฃจํŠธ ๋ฆฌ๋“€์„œ์ฒ˜๋Ÿผ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์†๊ธฐ๋Š” ์™„์ „ํ•œ ์ƒํƒœ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ถŒ์žฅ๋˜๋Š” ํ•˜์œ„ ๊ฐ์†Œ ๊ธฐ ํŒจํ„ด๋ณด๋‹ค ๋” ๋งŽ์€ ์•ก์„ธ์Šค๊ฐ€ ํ•„์š”ํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘์—…์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ๋‚จ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ถ„๋ช…ํžˆ ์ข‹์€ ์ƒ๊ฐ์€ ์•„๋‹ˆ์ง€๋งŒ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ•˜์œ„ ๊ฐ์†๊ธฐ์™€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฃจํŠธ ๊ฐ์†๊ธฐ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์ข‹์€ ์ด์ƒํ•œ ๊ฒฝ์šฐ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ๋ฃจํŠธ ๋ฆฌ๋“€์„œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋Œ€์‹  ์ค‘๊ฐ„ ๋‹จ๊ณ„์—์„œ ์ถ”๊ฐ€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ๊ด‘๋ฒ”์œ„ํ•œ ์•ก์„ธ์Šค๊ฐ€ ํ•„์š”ํ•œ ํ•˜์œ„ ๋ฆฌ๋“€์„œ๋ฅผ ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์—ฌ์ „ํžˆ ์ „์ฒด ์•ก์„ธ์Šค๋ณด๋‹ค ์ ์Œ). ์˜ˆ๋ฅผ ๋“ค๋ฉด :

function a (state, action) { /* only sees within a */ return state; }
function b (state, action) { /* only sees within b */ return state; }
function c (state, action) { /* only sees within c */ return state; }

function ab (state, action) { /* partial state containing a and b */ return state; }
function bc (state, action) { /* partial state containing b and c */ return state; }

let rootReducer = combineReducers(
  { a, b, c },
  [ 'a', 'b', ab ],
  [ 'b', 'c', bc ]
);

๋ถ€๋ถ„ ๋ฆฌ๋“€์„œ ๋ฐ ์ถ”๊ฐ€ ๋ฃจํŠธ ๋ฆฌ๋“€์„œ์— ๋Œ€ํ•œ PR์„ ์ œ์ถœํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ๋”์ฐํ•œ ์•„์ด๋””์–ด์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ์ถฉ๋ถ„ํ•œ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์œ ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ• ๋กœ๊ฒ ๊ณผ ๋Š๋ฆ… ๋‚˜๋ฌด ๊ฐ€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€ ๋ฐฐ์šฐ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. JavaScript๋Š” ์—ฌ๋Ÿฌ progammig ๋‹ค์ด์–ด๊ทธ๋žจ์ด ํ˜ผํ•ฉ๋˜์–ด ์žˆ์œผ๋ฉฐ ์šฐ๋ฆฌ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด์ œ FRP์™€ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ์ค‘ ์˜ฌ๋ฐ”๋ฅธ ๊ฒƒ์ด ํ˜ผ๋ž€ ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‚˜์—๊ฒŒ๋„ ํ˜ผ๋ž€์˜ ์ง€์ ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•˜๋‹ค. ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€ / ์†”๋ฃจ์…˜์„ ์—ฌ๊ธฐ์— ๊ฒŒ์‹œํ•˜์‹ญ์‹œ์˜ค.

์„ธ ๊ฐ€์ง€ ๋ฆฌ์†Œ์Šค ์œ ํ˜• (ํด๋ผ์ด์–ธํŠธ, ํ”„๋กœ์ ํŠธ, ์ž‘์—…)์˜ ๋ฐฐ์—ด์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ํ•˜์œ„ ๊ฐ์†Œ ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ( REMOVE_CLIENT )๋ฅผ ์‚ญ์ œํ•  ๋•Œ ๋ชจ๋“  ๊ด€๋ จ ํ”„๋กœ์ ํŠธ์™€ ์ž‘์—…์„ ์‚ญ์ œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์€ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์™€ ๊ด€๋ จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ž‘์—… ๊ฐ์†๊ธฐ๋Š” ์กฐ์ธ ๋…ผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ์ ํŠธ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—… ๊ฐ์†๊ธฐ๋Š” ์‚ญ์ œ์ค‘์ธ ํด๋ผ์ด์–ธํŠธ์— ์†ํ•œ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ ID์˜ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜จ ๋‹ค์Œ ์ €์žฅ์†Œ์—์„œ ์ผ์น˜ํ•˜๋Š” ์ž‘์—…์„ ์ œ๊ฑฐํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด๋กœ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

export default store => next => action => {
  next({ ...action, getState: store.getState });
}

๋”ฐ๋ผ์„œ ๋ชจ๋“  ์ž‘์—…์€ action.getState() ๋ฅผ ํ†ตํ•ด ๋ฃจํŠธ ์ €์žฅ์†Œ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@ rhys-vdw ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ •๋ง ์œ ์šฉํ•œ ๋ฏธ๋“ค์›จ์–ด :)

@ rhys-vdw ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค โ€“ ์ข‹์€ ํ•ด๊ฒฐ์ฑ… ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์—”ํ„ฐํ‹ฐ๊ฐ€ ๋‘ ๊ฐœ ์ด์ƒ์˜ ๋‹ค๋ฅธ ์—”ํ„ฐํ‹ฐ์—์„œ ๊ณต์œ ๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ ์ค‘ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒฝ์šฐ์™€ ๊ฐ™์ด ์—์ง€ ์ผ€์ด์Šค / ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์— ๋Œ€ํ•œ ๋‹น์‹ ์˜ ์ƒ๊ฐ์„ ๋“ฃ๊ณ  ์‹ถ์–ด์š”.
@gaearon ์ •๊ทœํ™” ๋œ ์—”ํ‹ฐํ‹ฐ์˜ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ Redux์— ๋ฌธ์„œํ™” ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

ํŠน๋ณ„ํ•œ ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๊ณ ์ด ์Šคํ‚ค๋งˆ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ์†๊ธฐ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ์ด๋ฅผ ์ž๋™ํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํ•ญ๋ชฉ์ด ์‚ญ์ œ ๋  ๋•Œ "์“ฐ๋ ˆ๊ธฐ"๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ "์•Œ๊ฒŒ"๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๋ชจ๋‘ ๋งค์šฐ ์†์œผ๋กœ ํ”๋“ค๋ฆฌ๊ณ  ๊ตฌํ˜„ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค :-). ๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” ์‚ญ์ œ๊ฐ€ ์‹ค์ œ ์ •๋ฆฌ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•  ์ •๋„๋กœ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋ธ์˜ status ํ•„๋“œ๋ฅผ ๋’ค์ง‘๊ณ  ํ•ญ๋ชฉ์„ ์„ ํƒํ•  ๋•Œ ์‚ญ์ œ ๋œ ํ•ญ๋ชฉ์„ ํ‘œ์‹œํ•˜์ง€ ์•Š๋„๋กํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ผ๋ฐ˜์ ์ธ ์ž‘์—…์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์‚ญ์ œ์‹œ ์ƒˆ๋กœ ๊ณ ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@gaearon ์ดˆ๊ณ ์† ๋‹ต์žฅ์„ ํ•˜๋‚˜์˜ ๊ฐ€์น˜๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ํ•ด๋‹น ์ฃผ์— CRUD ์ž‘์—…์ด ๋งŽ์€ ๊ฒฝ์šฐ ํ•ด๋‹น ์œ ๋ น ํ•ญ๋ชฉ์ด ๋‹น์‹ ์„ ๋„˜์–ด ๋œจ๋ฆด ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Redux ๊ฐ€ ์ •๊ทœํ™” ๋œ ์—”ํ‹ฐํ‹ฐ์™€ ์ž„๋ฒ ๋””๋“œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ชจ๋‘ ์ง€์›ํ•œ๋‹ค๋ฉด ์—์ด์Šค๊ฐ€ ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ชฉ์ ์— ๋งž๋Š” ์ „๋žต์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž„๋ฒ ๋””๋“œ ์—”ํ‹ฐํ‹ฐ์˜ ๊ฒฝ์šฐ Redux ๋ฌธ์„œ์— ๋”ฐ๋ผ ์•ˆํ‹ฐ ํŒจํ„ด ์ธ nested reducers ์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์†๊ธฐ์—์„œ ๋‚˜๋จธ์ง€ ์ €์žฅ ์ƒํƒœ์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๊ฒฝ์šฐ์—๋Š” ์ค‘์ฒฉ ๋œ combineReducers๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ์ •๋ง ์–ด๋ ต์Šต๋‹ˆ๋‹ค. .parent() ๋˜๋Š” .root() ๋˜๋Š” ์ด์™€ ๋™๋“ฑํ•œ ์ƒํƒœ์™€ ๊ฐ™์€ ๋‚˜๋จธ์ง€ ์ƒํƒœ์— ์•ก์„ธ์Šคํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ์†๊ธฐ์—์„œ ๋‹ค๋ฅธ ๊ฐ์†๊ธฐ์˜ ์ƒํƒœ์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒƒ์€ ๋Œ€๋ถ€๋ถ„ ์•ˆํ‹ฐ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.
์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐ์†๊ธฐ์—์„œ ํ•ด๋‹น ๋กœ์ง์„ ์ œ๊ฑฐํ•˜๊ณ  ์„ ํƒ๊ธฐ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ์กฐ์น˜์— ์ถ”๊ฐ€ ์ •๋ณด ์ „๋‹ฌ
  • ๋ทฐ ์ฝ”๋“œ๊ฐ€ ๋‘ ๊ฐ€์ง€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋„๋กํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌ! ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฃจํŠธ ์ƒํƒœ๋ฅผ ๊ฐ์†๊ธฐ์— ์ „๋‹ฌํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ ํ›„ ๋” ๋ณต์žกํ•ด์กŒ์Šต๋‹ˆ๋‹ค. :-)

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

์ข‹์•„, ๋‚˜๋Š” ์ •๊ทœํ™” ๋œ ์ƒํƒœ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์˜ ์ด์ ์„ ๋ถ„๋ช…ํžˆ๋ณด๊ณ  ๋‚ด ์ƒํƒœ ์ข…๋ฅ˜์˜ redux ๋ถ€๋ถ„์„ DB์ฒ˜๋Ÿผ ์ทจ๊ธ‰ํ•œ๋‹ค.

๋‚˜๋Š” ์—ฌ์ „ํžˆ @gaearon (์‚ญ์ œ๋ฅผ ์œ„ํ•ด ์—”ํ‹ฐํ‹ฐ ํ”Œ๋ž˜๊ทธ ์ง€์ •) ๋˜๋Š” @ rhys-vdw์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋” ๋‚˜์€์ง€ (์ฐธ์กฐ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๊ด€๋ จ ์ฐธ์กฐ๋ฅผ ์ œ์ž๋ฆฌ์—์„œ ์ œ๊ฑฐ) ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์•„์ด๋””์–ด / ์‹ค์ œ ๊ฒฝํ—˜์ด ์žˆ์Šต๋‹ˆ๊นŒ?

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

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

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

์ƒํƒœ๋ฅผ ๋ทฐ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์ƒํƒœ ๋ชจ์–‘ ๋ณ€๊ฒฝ์„ ์ฐจ๋‹จํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์ง€๋งŒ, ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋จ์— ๋”ฐ๋ผ ์ถ”๊ฐ€ ์ƒํƒœ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—…๋ฐ์ดํŠธํ•ด์•ผํ•˜๋Š” ๋งŽ์€ ์ž‘์—…๋งŒํผ์ด๋‚˜ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

๋ฆฌ๋“€์„œ๊ฐ€ ๋ฃจํŠธ ์ƒํƒœ์— ์•ก์„ธ์Šคํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” IMHO๋Š” ํ˜„์žฌ์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•๋ณด๋‹ค ์ „์ฒด์ ์ธ ์ปคํ”Œ ๋ง์ด ์ ์Šต๋‹ˆ๋‹ค.

@kurtharriger : ์ผ๋ฐ˜์ ์ธ ๊ถŒ์žฅ ํŒจํ„ด์€ ๋„๋ฉ”์ธ๋ณ„๋กœ Redux ์ƒํƒœ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  combineReducers ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๋„๋ฉ”์ธ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ๊ถŒ์žฅ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ์ „์ฒด ์ƒํƒœ๋ฅผ ํŠน์ • ํ•˜์œ„ ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ํฌํ•จํ•˜์—ฌ ์ƒํ™ฉ์„ ๋‹ค๋ฅด๊ฒŒ ๊ด€๋ฆฌํ•˜๋Š” ์ž์‹  ๋งŒ์˜ ์ตœ์ƒ์œ„ ๋ฆฌ๋“€์„œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ „์ ์œผ๋กœ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ถ๊ทน์ ์œผ๋กœ, ๋‹น์‹ ์€ ์ •๋ง๋กœ _ ํ•˜๋‚˜์˜ _ ๊ฐ์†๊ธฐ ๊ธฐ๋Šฅ๋งŒ์„ ๊ฐ€์ง€๊ณ  combineReducers ๋Š” ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์œ ์šฉํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ์ž…๋‹ˆ๋‹ค.

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋ถ„ํ• ์— ๋Œ€ํ•œ Redux FAQ ๋‹ต๋ณ€์—๋„์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ์ข‹์€ ํ† ๋ก ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ, ๋˜ ๋‹ค๋ฅธ ์˜ต์…˜์€ ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ํ•จ์ˆ˜์—์„œ ๋‹จ์ผ ๊ฐ์†๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋‚ด์žฅ ๋œ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์ž์‹  ๋งŒ์˜ combineReducer ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ถ”๊ฐ€ ๋ฃจํŠธ ์ƒํƒœ ์ธ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋‚ด์žฅํ˜• combineReducers ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์œ ์šฉ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ์ด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ PR์€ ์•ˆํ‹ฐ ํŒจํ„ด์œผ๋กœ ๋‹ซํ˜”์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” IMHO๋ฅผ ์ œ์•ˆํ•œ ๋Œ€์•ˆ์ด ํ›จ์”ฌ ๋” ์ „์ฒด์ ์ธ ๊ฒฐํ•ฉ์„ ์ดˆ๋ž˜ํ•œ๋‹ค๋Š” ์ ์„ ์ฃผ์žฅํ•˜๊ณ  ์‹ถ์—ˆ๊ณ  ์•„๋งˆ๋„ ์ด๊ฒƒ์€ ์•ˆํ‹ฐ ํŒจํ„ด์œผ๋กœ ๊ฐ„์ฃผ๋˜์–ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฃจํŠธ ์ƒํƒœ๊ฐ€ ์ถ”๊ฐ€ ์ธ์ˆ˜๋กœ ์ถ”๊ฐ€ ๋œ ๊ฒฝ์šฐ ๊ฐ•์ œ๋กœ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฅด๋ฏ€๋กœ ์ปคํ”Œ ๋ง์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์˜ตํŠธ ์ธ์ž…๋‹ˆ๋‹ค.

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

๋‚˜๋Š” redux / react์— ์ต์ˆ™ํ•˜์ง€ ์•Š์ง€๋งŒ ๊ฒธ์†ํ•˜๊ฒŒ ์ด๊ฒƒ์„ ๋ฌป์Šต๋‹ˆ๋‹ค. ์„œ๋กœ์˜ ์ƒํƒœ์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ตฌ์„ฑ๋œ ๊ฐ์†๊ธฐ๊ฐ€ ์ƒํƒœ ๋ชจ์–‘์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์˜์—ญ ์‚ฌ์ด์— ๊ฒฐํ•ฉ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•ˆํ‹ฐ ํŒจํ„ด์ด๋ผ๋ฉด์ด ๊ฒฐํ•ฉ์€ ์ด๋ฏธ mapStateToProps ( )์˜ ์—ฐ๊ฒฐ (), ๊ทธ ํ•จ์ˆ˜๋Š” ๋ฃจํŠธ ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋ชจ๋“  ๊ณณ์—์„œ / ์–ด๋””์—์„œ๋‚˜ ๊ฐ€์ ธ์™€ ์†Œํ’ˆ์„ ์–ป์Šต๋‹ˆ๋‹ค.

์ƒํƒœ ํ•˜์œ„ ํŠธ๋ฆฌ๋ฅผ ์บก์Šํ™”ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ํ•ด๋‹น ํ•˜์œ„ ํŠธ๋ฆฌ๋ฅผ ์ˆจ๊ธฐ๋Š” ์ ‘๊ทผ์ž๋ฅผ ํ†ตํ•ด ์ƒํƒœ์— ์•ก์„ธ์Šคํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ ๋ฆฌํŒฉํ† ๋ง์—†์ด ํ•ด๋‹น ๋ฒ”์œ„ ๋‚ด๋ถ€์˜ ์ƒํƒœ ๋ชจ์–‘์„ ๊ด€๋ฆฌ ํ•  ์ˆ˜ โ€‹โ€‹์žˆ์Šต๋‹ˆ๋‹ค.

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

@jwhiting : ์ด๋Š” ํŠนํžˆ mapStateToProps ์—์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒํƒœ์—์„œ ์ถ”์ถœํ•˜๊ธฐ ์œ„ํ•ด "์„ ํƒ๊ธฐ ํ•จ์ˆ˜"๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ชฉ์  ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. state.some.nested.field ์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹์‹ค์ œ๋กœ ์•Œ์•„์•ผํ•˜๋Š” ์ตœ์†Œํ•œ์˜ ์žฅ์†Œ ๋งŒ ์žˆ๋„๋ก ๋„ํ˜•์˜ ์ƒํƒœ๋ฅผ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„์ง ๋ณด์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด Reselect ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ Redux ๋ฌธ์„œ์˜ Computing Derived Data ์„น์…˜์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

๋„ค. ๋ฐ์ดํ„ฐ ๋ณผ๋ฅจ์ด ์ž‘์ง€๋งŒ ์—ฌ์ „ํžˆ (์†์œผ๋กœ ์“ด) ์„ ํƒ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋‹ค์‹œ ์„ ํƒ์„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์— ๋Œ€ํ•œ shopping-cart ์˜ˆ์ œ๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

@markerikson @gaearon ์ด ์˜๋ฏธ๊ฐ€ ์žˆ์œผ๋ฉฐ ํƒ์ƒ‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ฃผ์š” ๊ด€์‹ฌ์‚ฌ (๋˜๋Š” ๋ชจ๋“  ์ƒํƒœ ์•ก์„ธ์Šค)์— ๋Œ€ํ•ด mapStateToProps์˜ ์„ ํƒ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์™ธ๋ถ€ ์ƒํƒœ ๋ชจ์–‘์˜ ๋ณ€๊ฒฝ์œผ๋กœ๋ถ€ํ„ฐ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ณดํ˜ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด ํ”„๋กœ์ ํŠธ์—์„œ ์ƒํƒœ ์บก์Šํ™”๋ฅผ๋ณด๋‹ค ์—„๊ฒฉํ•˜๊ฒŒ ์‹œํ–‰ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ ์ฝ”๋“œ ๊ทœ์œจ์ด ์œ ์ผํ•œ ๊ฐ€๋“œ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ๊ฑฐ๊ธฐ์—์„œ ์ œ์•ˆ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ๋‹จ์ผ ๊ฐ์†๊ธฐ์— ๋ณด๊ด€ํ•˜๋Š” ๊ฒƒ์€
์šฐ๋ ค. ๊ฐ์†๊ธฐ๊ฐ€ ๋ฃจํŠธ์— ์˜ํ•ด ํ˜ธ์ถœ๋˜๋ฉด ์ˆ˜๋™์œผ๋กœ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์ œ์•ˆํ•œ๋Œ€๋กœ ๋ฃจํŠธ ์ƒํƒœ๋ฅผ ๋ช…์‹œ ์ ์œผ๋กœ ์ „๋‹ฌํ•˜์ง€๋งŒ
๋ถ€๋ชจ ๊ฐ์†๊ธฐ ๊ณ„์ธต์—๋Š” ๊ฒฐํ•ฉ ๊ฐ์†๊ธฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐ–. ๊ทธ๋Ÿฌ๋‹ˆ ์ฐข์„ ํ•„์š”๊ฐ€ ์—†๋„๋ก ์ข€ ๋” ํ•ฉ์„ฑ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?
๋‚˜์ค‘์— ๋‚˜๊ฐ€๊ฑฐ๋‚˜ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์ดํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ฝํฌ์— ์˜์ง€ํ•ฉ๋‹ˆ๊นŒ?
2016 ๋…„ 4 ์›” 16 ์ผ ํ† ์š”์ผ ์˜คํ›„ 8:27 Josh Whiting [email protected]
์ผ๋‹ค :

@markerikson https://github.com/markerikson @gaearon
https://github.com/gaearon ์ดํ•ด๊ฐ€๋˜๋ฉฐ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋ฐ–์˜ ๋ชจ๋“  ๊ฒƒ์— ๋Œ€ํ•ด mapStateToProps์—์„œ ์„ ํƒ๊ธฐ ์‚ฌ์šฉ
๊ตฌ์„ฑ ์š”์†Œ์˜ ์ฃผ์š” ๊ด€์‹ฌ์‚ฌ (๋˜๋Š” ๋ชจ๋“  ์ƒํƒœ ์•ก์„ธ์Šค์— ๋Œ€ํ•œ)๋Š”
์ด๋ฌผ์งˆ ๋ชจ์–‘์˜ ๋ณ€ํ™”๋กœ ์ธํ•œ ๊ตฌ์„ฑ ์š”์†Œ. ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค
ํ•˜์ง€๋งŒ ๋‚ด ํ”„๋กœ์ ํŠธ์—์„œ ์ƒํƒœ ์บก์Šํ™”๋ฅผ ๋” ์—„๊ฒฉํ•˜๊ฒŒ ์‹œํ–‰ํ•˜๊ธฐ ์œ„ํ•ด
๊ทธ๋ž˜์„œ ์ฝ”๋“œ ๊ทœ์œจ ๋งŒ์ด ๊ทธ๊ฒƒ์„ ๋ณดํ˜ธํ•˜๊ณ  ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.
๊ฑฐ๊ธฐ์— ์ œ์•ˆ.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/reactjs/redux/issues/601#issuecomment -210940305

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

์šฐ๋ฆฌ๋Š” ํŒจํ„ด๊ณผ ์šฐ๋ ค์˜ ๋ถ„๋ฆฌ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ๋Š” ๊ด€๋ จ์ด ์žˆ์ง€๋งŒ ๋Œ€์‹  ํ–‰๋™์„ ์ทจํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

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

@shadowii ์•ก์…˜ ํฌ๋ฆฌ์—์ดํ„ฐ๊ฐ€ ์„ ํƒ๊ธฐ๋ฅผ ๊ฐ€์ ธ ์˜ค๋Š” ๊ฒƒ์€ ๊ดœ์ฐฎ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์„ ํƒ๊ธฐ์™€ ๊ฐ์†๊ธฐ๋ฅผ ํ•จ๊ป˜ ๋ฐฐ์น˜ํ•˜์—ฌ ์ƒํƒœ ๋ชจ์–‘์— ๋Œ€ํ•œ ์ง€์‹์ด ํ•ด๋‹น ํŒŒ์ผ์— ์ง€์—ญํ™”๋ฉ๋‹ˆ๋‹ค.

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

๋‹ค๋ฅธ ๊ฐ์†๊ธฐ๊ฐ€ ๋™์ผํ•œ ์ž‘์—… ์œ ํ˜•์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ์ผ๋ฐ˜์ ์ด๊ณ  ์œ ์šฉํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ์‚ฌ์‹ค ๊ทธ๊ฒƒ์€ _reason_ ์•ก์…˜์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์•ก์…˜์ด ๋ฆฌ๋“€์„œ 1 : 1์— ๋งคํ•‘๋œ๋‹ค๋ฉด, ์•ก์…˜์„ ๊ฐ–๋Š” ๊ฒƒ์€ ๊ฑฐ์˜ ์˜๋ฏธ๊ฐ€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@ rhys-vdw ๊ฒŒ์‹œ ํ•œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

customMiddleare.js

const customMiddleware =  store => next => action => {
  next({ ...action, getState: store.getState });
};

๊ทธ๋ฆฌ๊ณ  ๋‚ด ์ƒ์  ์ƒ์„ฑ์—๋Š”

import customMiddleware from './customMiddleware';

var store = createStore(
        rootReducer,
        initialState,
        applyMiddleware(
            reduxPromise,
            thunkMiddleware,
            loggerMiddleware,
            customMiddleware
        )
    );
return store;

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

applyMiddleware.js? ee15 : 49 Uncaught TypeError : ๋ฏธ๋“ค์›จ์–ด๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค (โ€ฆ)
(์ต๋ช… ํ•จ์ˆ˜) @ applyMiddleware.js? ee15 : 49
(์ต๋ช… ํ•จ์ˆ˜) @ applyMiddleware.js? ee15 : 48
createStore @ createStore.js? fe4c : 65
configureStore @ configureStore.js? ffde : 45
(์ต๋ช… ํ•จ์ˆ˜) @ index.jsx? fdd7 : 25
(์ต๋ช… ํ•จ์ˆ˜) @ bundle.js : 1639
webpack_require @ bundle.js : 556
fn @ bundle.js : 87 (์ต๋ช… ํ•จ์ˆ˜) @ bundle.js : 588
webpack_require @ bundle.js : 556
(์ต๋ช… ํ•จ์ˆ˜) @ bundle.js : 579
(์ต๋ช… ํ•จ์ˆ˜) @ bundle.js : 582

@ mars76 : ์•„๋งˆ๋„ ๋ฌด์–ธ๊ฐ€๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฐ€์ ธ ์˜ค์ง€ ์•Š์•˜์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์‹ค์ œ๋กœ customMiddleware.js ์˜ ์ „์ฒด ๋‚ด์šฉ์ด๋ผ๋ฉด _anything_์„ ๋‚ด ๋ณด๋‚ด์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ 4 ๊ฐœ์˜ ๋ฏธ๋“ค์›จ์–ด๋ฅผ applyMiddleware ์— ์ „๋‹ฌํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๊ทธ์ค‘ ํ•˜๋‚˜๋Š” ์œ ํšจํ•œ ์ฐธ์กฐ๊ฐ€ ์•„๋‹ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋’ค๋กœ ๋ฌผ๋Ÿฌ๋‚˜์„œ ๋ชจ๋‘ ์ œ๊ฑฐํ•˜๊ณ  ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ๋‹ค์‹œ ์ถ”๊ฐ€ํ•˜๊ณ  ์–ด๋–ค ๊ฒƒ์ด ์œ ํšจํ•˜์ง€ ์•Š์€์ง€ ํ™•์ธํ•˜๊ณ  ์ด์œ ๋ฅผ ํŒŒ์•…ํ•˜์‹ญ์‹œ์˜ค. ๊ฐ€์ ธ ์˜ค๊ธฐ ๋ฐ ๋‚ด๋ณด๋‚ด๊ธฐ ๋ฌธ์„ ํ™•์ธํ•˜๊ณ  ํ•ญ๋ชฉ์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค์‹œ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

์•ˆ๋…•ํ•˜์„ธ์š”,

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @markerikson

๊ตฌ๋ฌธ์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€ํ™˜ํ–ˆ๋Š”๋ฐ ์ด์ œ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

customMiddleware.js

export function customMiddleware(store) { return function (next) { return function (action) { next(Object.assign({}, action, { getState: store.getState })); }; }; } console.log(customMiddleware);

์–ด๋–ป๊ฒŒ ๋‚ด๊ฐ€ Action Creator ์ž์ฒด (Reducer๊ฐ€ ์•„๋‹˜)์—์„œ ์ƒ์ ์— ์•ก์„ธ์Šคํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Async ํ˜ธ์ถœ์„ํ•ด์•ผํ•˜๊ณ  ๋‹ค์–‘ํ•œ ๊ฐ์†๊ธฐ์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ์ƒ์  ์ƒํƒœ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ์ „๋‹ฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์•ก์…˜์„ ์ „๋‹ฌํ•˜๊ณ  ๊ฐ์†๊ธฐ ๋‚ด๋ถ€์—์„œ ์ด์ œ ์ „์ฒด State์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ์ถ”์ถœํ•˜๊ณ  Object๋ฅผ ์ƒ์„ฑํ•˜๊ณ ์ด ๋ฐ์ดํ„ฐ๋กœ ๋‹ค๋ฅธ ์•ก์…˜์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.์ด ๋ฐ์ดํ„ฐ๋Š” ๋‚ด Action Creator์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Asyn ํ˜ธ์ถœ์„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ๊ฐ€์žฅ ํฐ ๊ด€์‹ฌ์‚ฌ๋Š” Reducer๊ฐ€ ์ด์ œ ์•ก์…˜ ์ƒ์„ฑ๊ธฐ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜๊ฒฌ์„ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌ

@ mars76 : ๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ๊ฐ์†๊ธฐ ๋‚ด์—์„œ ๋””์ŠคํŒจ์น˜๋ฅผ โ€‹โ€‹์‹œ๋„ํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค .

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

@markerikson์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๋‚ด ์ž˜๋ชป์ด์•ผ redux-thunk์˜ getState ()์— ๋Œ€ํ•ด ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚ด ์ผ์„ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ณ  ๋‚ด ๊ฐ์†๊ธฐ๋ฅผ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

@gaearon ์•ก์…˜ ์ƒ์„ฑ์ž๊ฐ€ ์„ ํƒ์ž๋ฅผ ๊ฐ€์ ธ ์˜ค๋Š” ๊ฒƒ์„ ์–ธ๊ธ‰ํ–ˆ์„ ๋•Œ ์ „์ฒด ์ƒํƒœ๊ฐ€ ์„ ํƒ์ž์—๊ฒŒ ์ „๋‹ฌ๋˜๋„๋ก ์•ก์…˜ ์ƒ์„ฑ์ž์—๊ฒŒ ์ „๋‹ฌ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์—ผ๋‘์— ๋‘ ์…จ๋‚˜์š”? ์•„๋‹ˆ๋ฉด ๋ญ”๊ฐ€ ๋น ์กŒ๋‚˜์š”?

@tacomanator : ์ฐธ๊ณ ๋กœ Dan์€ ์š”์ฆ˜ Redux ๋ฌธ์ œ์—์„œ ๋ฌด์ž‘์œ„ ํ•‘์— ์ผ๋ฐ˜์ ์œผ๋กœ ์‘๋‹ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์•ก์…˜ ์ œ์ž‘์ž์—์„œ ์„ ํƒ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ฝํฌ ๋‚ด์—์„œ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. Thunk๋Š” getState ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ „์ฒด ์ƒํƒœ ํŠธ๋ฆฌ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import {someSelector} from "./selectors";

function someThunk(someParameter) {
    return (dispatch, getState) => {
        const specificData = someSelector(getState(), someParameter);

        dispatch({type : "SOME_ACTION", payload : specificData});    
    }
}

@markerikson ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๋‚ด๊ฐ€ ๋ฌป๋Š” ์ด์œ ๋Š” ์ฃผ๋กœ ๋ฆฌ๋“€์„œ๋กœ ๋ณด๋‚ด๋Š” ๊ฒƒ๊ณผ๋Š” ๋Œ€์กฐ์ ์œผ๋กœ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์œ„ํ•ด ์„ ํƒ์ž์—์„œ ํŒŒ์ƒ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๊ด€ํ•œ ๊ฒƒ์ด์ง€๋งŒ, ์ƒ๊ฐํ•  ์ˆ˜์žˆ๋Š” ์Œ์‹๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์†๊ธฐ๋ฅผ ํ•˜๋‚˜๋กœ ๊ฒฐํ•ฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ ๋น ๋ฅธ ํ•ดํ‚น์€

const reducers = [ reducerA, reducerB, ..., reducerZ ];

let reducer = ( state = initialState, action ) => {
    return reducers.reduce( ( state, reducerFn ) => (
        reducerFn( state, action )
    ), state );
};

์—ฌ๊ธฐ์„œ reducerA ์—์„œ reducerZ ๋Š” ๊ฐœ๋ณ„ ๊ฐ์†๊ธฐ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

@brianpkelley : ๋„ค, ๊ธฐ๋ณธ์ ์œผ๋กœ https://github.com/acdlite/reduce-reducers ์ž…๋‹ˆ๋‹ค.

@markerikson ์•„, ์ฒ˜์Œ์œผ๋กœ react / redux / etc๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ด ๋ฌธ์ œ๋ฅผ ์กฐ์‚ฌํ•˜๋Š” ๋™์•ˆ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ˜์ฏค ๋๊นŒ์ง€ ๊ฑด๋„ˆ ๋›ฐ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ—ค, ๋ฌผ๋ก ์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ " combineReducers ๋ฅผ) ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?" ๋ผ๋Š” . ๋ฐ ๋ฌธ์„œ์˜ ๊ตฌ์กฐํ™” ๊ฐ์†๊ธฐ ์„น์…˜. ๋˜ํ•œ ์ €์˜ "Practical Redux"ํŠœํ† ๋ฆฌ์–ผ ์‹œ๋ฆฌ์ฆˆ ์—๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ณ ๊ธ‰ ๊ฐ์†๊ธฐ ๊ธฐ์ˆ ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฒŒ์‹œ๋ฌผ์ด ์žˆ์Šต๋‹ˆ๋‹ค (7 ๋ถ€ ๋ฐ 8 ๋ถ€ ์ฐธ์กฐ).

redux-logic์„ ์‚ฌ์šฉํ•  ๋•Œ ๋‚ด ๋‘ ์„ผํŠธ๋Š” transform ํ•จ์ˆ˜์˜ ๋ฃจํŠธ ์ƒํƒœ์—์„œ ์ž‘์—…์„ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ:

const formInitLogic = createLogic({
  type: 'FORM_INIT',
  transform({ getState, action }, next) {
    const state = getState();
    next({
      ...action,
      payload: {
        ...action.payload,
        property1: state.branch1.someProperty > 5,
        property2: state.branch1.anotherProperty + state.branch2.yetAnotherProperty,
      },
    });
  },
});

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

  • redux ๋ฃจํŠธ

    • reducers.js ๋‚ด๋ณด๋‚ด๊ธฐ๋Š” ๋ชจ๋“  ์ƒํƒœ์˜ ๊ฐ์†๊ธฐ๋ฅผ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.

    • middleware.js export applyMiddleware for all middleware

    • configureStore.js createStore ์‚ฌ์šฉ (reducers.js, middleware.js)

    • actions.js ๋Š” ์ƒํƒœ ํด๋”์—์„œ ์ž‘์—…์„ ์ „๋‹ฌํ•˜๋Š” ์ž‘์—… ๋‚ด๋ณด๋‚ด๊ธฐ <== THIS

    • state1

    • initial.js ์ด ํŒŒ์ผ์€ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค (๋‚˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ถˆ๋ณ€์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค)

    • action-types.js ์ด ํŒŒ์ผ์—๋Š” ์ž‘์—… ์œ ํ˜•์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค (dacho๋ฅผ ํ‚ค ๋ฏธ๋Ÿฌ๋กœ ์‚ฌ์šฉ).

    • actions.js ์ด ํŒŒ์ผ์—๋Š” ์ƒํƒœ ์ž‘์—…์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

    • reducer.js ์ด ํŒŒ์ผ์—๋Š” ์ƒํƒœ ๊ฐ์†๊ธฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

    • state2

    • initial.js

    • action-types.js

      ....

์™œ ?
1- ๋ชจ๋“  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—๋Š” ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ์ž‘์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ƒํƒœ ์ž‘์—… (redux / state1 / actions.js) ์ด๋Ÿฌํ•œ ์ž‘์—…์€ ์ƒํƒœ ๋ณ€๊ฒฝ์—๋งŒ ์ฑ…์ž„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์ง์ ‘ ์‹คํ–‰ํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค. ํ•ญ์ƒ ์•ฑ ์ž‘์—…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    • ์•ฑ ์ž‘์—… (redux / actions.js) ์ด๋Ÿฌํ•œ ์ž‘์—…์€ ์ผ๋ถ€ ์•ฑ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ƒํƒœ ์ž‘์—…์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2- ์ถ”๊ฐ€๋กœ์ด ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋”๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ๊ณ  ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์ƒˆ ์ƒํƒœ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

2 ๊ฐœ์˜ ๊ฐ์†๊ธฐ๊ฐ€ ๋™์ผํ•œ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

๋‹ค๋ฅธ ํŒŒ์ผ๋กœ ๋ถ„ํ• ํ•˜๊ณ  ์‹ถ์€ ๊ฐ์†๊ธฐ๊ฐ€ ์žˆ๊ณ  http ์š”์ฒญ์ด ์–ด๋–ค ์ด์œ ๋กœ ์‹คํŒจ ํ•  ๋•Œ ๋ณ€๊ฒฝํ•˜๋Š” 'error'๋ผ๋Š” ์†์„ฑ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ • ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด์ œ ์–ด๋Š ์‹œ์ ์—์„œ ๊ฐ์†๊ธฐ๊ฐ€ ์ปค์ ธ์„œ ์—ฌ๋Ÿฌ ๊ฐ์†๊ธฐ๋กœ ๋ถ„ํ• ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์ง€๋งŒ ๋ชจ๋‘ '์˜ค๋ฅ˜'์†์„ฑ์„ ๋ณ€๊ฒฝํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ญ?

@ Wassap124 ๋‘ ๊ฐ์†๊ธฐ๊ฐ€ ๋™์ผํ•œ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋‘ ๊ฐ€์ง€ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ?

๋” ์ž์„ธํ•œ ์ •๋ณด๊ฐ€ ์—†์œผ๋ฉด ์ฝํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ "์˜ค๋ฅ˜ ์„ค์ •"์ž‘์—…์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@ rhys-vdw ๋‚˜๋Š” ๊ฝค ๊ธด ๊ฐ์†๊ธฐ๋ฅผ ๋‚˜๋ˆ„๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋‹น์‹ ์˜ ์ œ์•ˆ๊ณผ ๊ด€๋ จํ•˜์—ฌ ๋ถ€์ž‘์šฉ์ด ์—†๋‹ค๋Š” ๊ทœ์น™๊ณผ ๋ชจ์ˆœ๋˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

@ Wassap124 , @ rhys-vdw : ๋ช…ํ™•ํžˆํ•˜๊ธฐ ์œ„ํ•ด, combineReducers _ ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‘ ๊ฐœ์˜ ๊ฐ์†๊ธฐ๊ฐ€ ๋™์ผํ•œ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž์‹ ์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋งž๊ฒŒ ๋‹ค๋ฅธ ๋ฆฌ๋“€์„œ ๋กœ์ง์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://redux.js.org/recipes/structuringreducers/beyondcombinereducers๋ฅผ ์ฐธ์กฐ

๋น ๋ฅธ ์†Œ์Šค ์„ค๋ช…์„ํ•œ๋‹ค๋ฉด ...

combineReducers ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜ ์„œ๋ช…์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

return function combination(state = {}, action) {

https://github.com/reduxjs/redux/blob/master/src/combineReducers.js#L145 ์ฐธ์กฐ

์‹ค์ œ ๊ฐ์†๊ธฐ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•ด ํด๋กœ์ €๋ฅผ ๋งŒ๋“  ํ›„.

๋”ฐ๋ผ์„œ ์ €์žฅ์†Œ์—์„œ ์ƒํƒœ๋ฅผ ์ˆ˜ํ™”ํ•˜๊ณ  ๋‹ค์‹œ๋กœ๋“œํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์ž‘์—…์„ ์ „์—ญ ์ ์œผ๋กœ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ โ€‹โ€‹์žˆ๋„๋ก ๊ฐ„๋‹จํ•œ ๊ฒƒ์„ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const globalReducerHandler = () => {
  return (state = {}, action) => {
    if (action.type === 'DO_GLOBAL_THING') {
      return globallyModifyState(state)
    }
    return reducers(state, action)
  }
}

์ด๊ฒƒ์€ ๋ฐ˜ ํŒจํ„ด ์ผ ์ˆ˜๋„ ์žˆ๊ณ  ์•„๋‹ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์‹ค์šฉ์ฃผ์˜๋Š” ํ•ญ์ƒ ๋” ์ค‘์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๊ฐ์†๊ธฐ์—์„œ ๊ฐ์†๊ธฐ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹  (globalReducerHandler๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” ๊ฐ์†๊ธฐ์™€ ๊ด€๋ จ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์•ˆํ‹ฐ ํŒจํ„ด์ž…๋‹ˆ๋‹ค) reduceReducers ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ์†๊ธฐ์˜ ๊ฒฝ์šฐ ๋ณธ์งˆ์ ์œผ๋กœ compose ์ž…๋‹ˆ๋‹ค ๋ฌธ์ž ๊ทธ๋Œ€๋กœ (Action ->) ๋ชจ๋‚˜๋“œ์—์„œ ๊ตฌ์„ฑ).

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰