Redux: ์—ฌ๋Ÿฌ ๊ฐ์†๊ธฐ ๋ชจ๋“ˆ ๊ฐ€์ ธ ์˜ค๊ธฐ๊ฐ€์žˆ๋Š” ํ•จ์ˆ˜ combineReducers์— ๋Œ€ํ•œ ์งˆ๋ฌธ

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

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

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ์†๊ธฐ ํŒŒ์ผ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ • ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

export function something1 (state={}, action) {
  switch (action.type) {
    ...
  }
}

export function something2 (state={}, action) {
  switch (action.type) {
    ...
  }
}

์—ฌ๋Ÿฌ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€์žˆ๋Š” 3 ๊ฐœ์˜ ๋‹ค๋ฅธ ์œ ์‚ฌํ•œ ๊ฐ์†๊ธฐ ํŒŒ์ผ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์„œ๋Š” ๋‹จ์ง€ ํ•˜๋‚˜์˜ ํŒŒ์ผ๊ณผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€์žˆ๋Š” CombineReducers๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์˜ˆ์ œ๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ -combineReducers |

๊ทธ๋ ‡๋‹ค๋ฉด ์ด์™€ ๊ฐ™์€ ์—ฌ๋Ÿฌ ๊ฐ€์ ธ ์˜ค๊ธฐ์—์„œ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?

import * as reducers1 from './reducer1';
import * as reducers2 from './reducer2';
...

const reducer = combineReducers(???); // What argument to write. How to turn imports to object?

๊ฐ์‚ฌ!

question

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

_are_ ๊ฐœ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์ฒด๋ฅผ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

import * as reducers1 from './reducer1';
import * as reducers2 from './reducer2';

const allReducers = Object.assign({}, reducers1, reducers2);
const reducer = combineReducers(allReducers);

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

_are_ ๊ฐœ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์ฒด๋ฅผ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

import * as reducers1 from './reducer1';
import * as reducers2 from './reducer2';

const allReducers = Object.assign({}, reducers1, reducers2);
const reducer = combineReducers(allReducers);

๋น ๋ฅธ ๋‹ต๋ณ€์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ES6๊ฐ€ ๊ทธ๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ ํ•œ ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. : +1 :
redux ๋ฌธ์„œ์— ๊ทธ๋Ÿฐ ๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฒƒ์„ ์ถ”๊ตฌํ•œ๋‹ค๋ฉด ๊ฐ€์น˜๊ฐ€ ์žˆ์„์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

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

์šฐ๋ฆฌ๋Š” ์‹ค์ œ๋กœ ๋ฌธ์„œ์—์„œ import * ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์„ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋‹๋ผ ์˜ˆ์ œ ๋งŒ ๋ณด์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. https://github.com/rackt/redux/pull/590์„ ์ฐธ์กฐ

๋น ๋ฅธ ๋‹ต๋ณ€์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ES6๊ฐ€ ๊ทธ๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ ํ•œ ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

ํด๋ฆฌ ํ•„์„ ํฌํ•จํ•˜์ง€ ์•Š๊ณ  ์ด๋ฏธ Lodash ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด Lodash์˜ assign ์™€ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ์ฒด๋ฅผ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค. ๋งˆ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค. :-)

@gaearon import * ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ฒ˜์Œ ์‚ฌ์šฉํ•  ๋•Œ ๋น„ ๊ตฌ์กฐํ™” ๋ฌธ๊ณผ ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๊ฐ€ ์ฃผ์„์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์Šต๋‹ˆ๋‹ค.

combineReducers ๋‹ค์ค‘ ํ†ตํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ?
๋ณ„๋„์˜ ํŒŒ์ผ์—์„œ combineReducers ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ฐ์†๊ธฐ๋ฅผ ํ•˜๋‚˜ ๋” ์ฒจ๋ถ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด (์‹ค์ œ๋กœ routerReducer ์—์„œ react-router-redux ) ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž ( ...reducers, routing: routerReducer )๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜์—†๋Š” ์ฃผ์š” ๋ฌธ์ œ๋Š” ์Šคํ…Œ์ด์ง• ๋œ ES6 ๊ธฐ๋Šฅ ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™•์‚ฐ ์—ฐ์‚ฐ์ž (... reducers, routing : routerReducer)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜์—†๋Š” ์ฃผ์š” ๋ฌธ์ œ๋Š” ์Šคํ…Œ์ด์ง• ๋œ ES6 ๊ธฐ๋Šฅ ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋‹จ์ง€ Object.assign({}, reducers, { routing: routerReducer }) desugars๋ฉ๋‹ˆ๋‹ค. Object.assign() ๋Š” ES6์˜ ์ผ๋ถ€์ด๋ฉฐ์ด๋ฅผ ์œ„ํ•ด ํด๋ฆฌ ํ•„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์†์œผ๋กœ ํ•ฉ๋ฆฌ์ ์ธ ๊ทผ์‚ฌ๊ฐ’์„ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

let finalReducers = {}
Object.keys(reducers).forEach(key => finalReducers[key] = reducers[key])
finalReducers.routing = routerReducer

const reducer = combineReducer(finalReducers)

๊ทธ๊ฒƒ์€ ๋ชจ๋‘ ๋‹จ์ง€ JavaScript์ž…๋‹ˆ๋‹ค!

๋น ๋ฅธ ์‘๋‹ต์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!
์ด ์งˆ๋ฌธ์„ํ•˜๊ธฐ ์ „์— Object.assign() ์„ ์–ธ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๊ฒฐํ•ฉํ•˜๊ธฐ ์ „์— rootReducer ๊ฐœ์ฒด์™€ default: function combination() ์†์„ฑ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ var reducer = Object.assign({}, rootReducer, { routing: routerReducer }) ์‚ฌ์šฉ ํ›„ ๋‚ด ๋ณ€์ˆ˜ reducer ์—๋Š” routing: function routerReducer() ์†์„ฑ
combineReducer(finalReducers) ํ›„ ๋ผ์šฐํŒ…์ด ์žˆ์ง€๋งŒ ๋‚ด ์•ฑ ๊ฐ์†๊ธฐ๊ฐ€์—†๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ญ”๊ฐ€ ์ž˜๋ชปํ•œ ๊ฒƒ ๊ฐ™์ง€๋งŒ ์ •ํ™•ํžˆ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•  ์ˆ˜ ์—†๋‹ค.

ํ•˜์ง€๋งŒ Object.keys ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์— ๋Œ€ํ•ด ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

default ์ด ํ‘œ์‹œ๋˜๋ฉด CommonJS require ๋กœ ES ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๊ณ  ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์‹ค์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ •๋ณด๋Š” https://medium.com/@kentcdodds/misunderstanding -es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

์ด๊ฒƒ์„ ์žฌํ˜„ ํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฒŒ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ธฐ๊บผ์ด ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ์ด๋ ‡๊ฒŒํ•œ๋‹ค :

mainReducer.js

import {combineReducers} from 'redux'
import {routerReducer} from 'react-router-redux'

// list of reducers
import registerReducer from 'registerReducer'
import homeReducer from 'homeReducer'
import aboutReducer from 'aboutReducer'
import contactUsReducer from 'contactUsReducer'


export const mapStateToProps = (state) => {
    return {
        register: state.register,
        home: state.home,
        about: state.about,
        contact:state.contact
    }
}
export default combineReducers({
    routing: routerReducer,
    register: registerReducer,
    home: homeReducer,
    about: aboutReducer,
    contact: contactUsReducer
})

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

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