Redux: createStore์—์„œ initialState๋ฅผ ์ œ๊ณตํ•œ ๋‹ค์Œ CombineReducers๋Š” ์ดˆ๊ธฐํ™” ์ค‘์— ์ •์˜๋˜์ง€ ์•Š์€ ๋ฐ˜ํ™˜๋œ ๋‚ด ๊ฐ์†๊ธฐ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

๊ฐ์†๊ธฐ์—์„œ:

const todoBlog = combineReducers({
  blogTypeVisibilityFilter,
  blogs
})

blogTypeVisibilityFilter์—์„œ:

const blogTypeVisibilityFilter = (state, action)=>{
  switch (action.type) {
    case 'BLOG_TYPE_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

export default blogTypeVisibilityFilter;

๋ธ”๋กœ๊ทธ์—์„œ:

const blogs = (state,action)=>{
  return state
}

createStore์—์„œ:

const initialState = {
  blogTypeVisibilityFilter:'SHOW_ALL_BLOG',
  blogs:data.data,
}

const store = createStore(reducer,initialState,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ž˜๋ชป ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋™์•ˆ ๊ฐ์†๊ธฐ "blogTypeVisibilityFilter"๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์Œ์„ ๋ฐ˜ํ™˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์†๊ธฐ์— ์ „๋‹ฌ๋œ ์ƒํƒœ๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ์ƒํƒœ๋Š” ์ •์˜๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ์†๊ธฐ์— ๋Œ€ํ•œ ๊ฐ’์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด undefined ๋Œ€์‹  null์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ๋ฐ”๋€” ๋•Œ

const todoBlog = combineReducers({
  blogTypeVisibilityFilter,
  blogs
})

์—๊ฒŒ

const todoBlog = (state={},action)=>{
  return{
    blogTypeVisibilityFilter:blogTypeVisibilityFilter(state.blogTypeVisibilityFilter,action),
    blogs:blogs(state.blogs,action)
  }
}

๊ฐ์†๊ธฐ์—์„œ๋Š” ์˜ค๋ฅ˜ ์—†์ด ์ž˜ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

์™œ ๋‚˜๋Š” CombineReducers๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์€ ์ž˜๋ชป๋ฉ๋‹ˆ๊นŒ?

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

์ด๊ฒƒ์€ ์ง€์› ์‹œ์Šคํ…œ์ด ์•„๋‹Œ ๋ฒ„๊ทธ ์ถ”์ ๊ธฐ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์งˆ๋ฌธ์€ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ ๋˜๋Š” Reactiflux๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๊ฐ์‚ฌ ํ•ด์š”!

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

์ด๊ฒƒ์€ ์ง€์› ์‹œ์Šคํ…œ์ด ์•„๋‹Œ ๋ฒ„๊ทธ ์ถ”์ ๊ธฐ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์งˆ๋ฌธ์€ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ ๋˜๋Š” Reactiflux๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๊ฐ์‚ฌ ํ•ด์š”!

๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ๊ณ„:

  1. ์ด๋ฏธ์ง€ ๋‹จ์ˆœ ์ƒ์  ๋ชจ์–‘ { foo, bar } .
  2. simpleReducer = state => state ์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ๊ฐ์†๊ธฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  3. reducers = combineReducers({ foo: simpleReducer, bar: simpleReducer }) ์—์„œ ๊ฐ์†๊ธฐ๋ฅผ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  4. createState(reducers, { foo: Obj1, bar: Obj2 }) ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์ƒํƒœ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  5. ์˜ค๋ฅ˜ Reducer "foo" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state

์ด์œ ๋Š” ์ดˆ๊ธฐ ์ƒํƒœ ๋ถ€๋ถ„์„ ์–ป๊ธฐ ์œ„ํ•ด ์ •์˜๋˜์ง€ ์•Š์€ ์ƒํƒœ ๋กœ ์‹คํ–‰ ํ•˜๋Š” assertReducerShape ์ž…๋‹ˆ๋‹ค. ๋‚ด ๊ฐ„๋‹จํ•œ ๊ฐ์†๊ธฐ๋Š” ์ด ๊ฒฝ์šฐ ์ •์˜๋˜์ง€ ์•Š์€ ์ธ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. createState ํ˜ธ์ถœ์˜ Obj1 ๊ฐ€ foo-part์˜ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@timdorr ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ simpleReducer = (state = null) => state ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ดœ์ฐฎ์•„?

combineReducers ํ•˜๋ฉด ๊ฐ ์Šฌ๋ผ์ด์Šค ๋ฆฌ๋“€์„œ๋Š” ํ•ด๋‹น ์ƒํƒœ ์Šฌ๋ผ์ด์Šค๋ฅผ "์†Œ์œ "ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ˜„์žฌ ์Šฌ๋ผ์ด์Šค๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ดˆ๊ธฐ ๊ฐ’์„ ์ œ๊ณตํ•˜๊ณ , ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ combineReducers ๊ฐ€ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

'์ดˆ๊ธฐ ์ƒํƒœ'์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. reducer์˜ ๊ธฐ๋ณธ ๋ฐ˜ํ™˜ ๊ฐ’๊ณผ createStore์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. CombineReducers๊ฐ€ initialState ๋ฐ createState์— ๋Œ€ํ•œ ๋ฆฌ๋“€์„œ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@Vittly : combineReducers ๋Š” ๊ณ ์˜์ ์œผ๋กœ ์˜๊ฒฌ์ด ๋ถ„๋ถ„ํ•œ ๋ฐ˜๋ฉด createStore ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. createStore ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ๋ถ€์—ฌํ•œ ๋ฃจํŠธ ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋ฅผ ๋‹จ์ˆœํžˆ ํ˜ธ์ถœํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. combineReducers ๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ƒํƒœ๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•˜๊ณ  ๊ฒฐํ•ฉ๋œ ๋ฆฌ๋“€์„œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ํŠน์ • ๊ฐ€์ • ์„ธํŠธ๋ฅผ ๊ตฌ๋งคํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

combineReducers ์ด(๊ฐ€) ๋…๋‹จ์ ์ด๋ฉฐ ์–ด๋–ค ์˜๊ฒฌ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์—ญ์‚ฌ์™€ ์„ธ๋ถ€ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๋Š” #191 ๋ฐ #1189๋ฅผ ์ฝ๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฌธ์ œ๋Š” (๊ฐ„๋‹จํžˆ) "๋ฆฌ๋“€์„œ๋ฅผ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒฝ์šฐ ์ €์žฅ์†Œ ํŠธ๋ฆฌ๋„ ๋ถ„ํ• ํ•˜๊ณ  ๋ฌด์–ธ๊ฐ€๋ฅผ ๋†“์น˜๊ฑฐ๋‚˜ createStore 2nd ์ธ์ˆ˜์—์„œ ์˜๋„์ ์œผ๋กœ ์ €์žฅ์†Œ์˜ ์ผ๋ถ€๋งŒ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €์žฅ์†Œ ํŠธ๋ฆฌ๋ฅผ ๋ณด๋‹ค ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์‚ฌ์šฉํ•˜๋ ค๋ฉด assertReducerShape๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค." ์ข‹์•„์š”, ์‹ฌํŒ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ createStore ํ•˜๊ณ  ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ reduct.js ํŒŒ์ผ์—์„œ assertReducerShape redux ํ•จ์ˆ˜๋Š” undefined ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ๋‚ด ๊ฐ์†๊ธฐ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

IMHO ์ด๊ฒƒ์€ ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค.

@JoseFMP : ๋‚˜๋Š” ๋‹น์‹ ์ด ๋ณด๊ณ  ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ๋ฒ„๊ทธ๊ฐ€

ํ™•์‹ ํ•˜๋Š”. Stackoverflow์—์„œ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค.
https://stackoverflow.com/questions/53018766/why-redux-reducer-getting-undefined-instead-of-the-initial-state

๋ฌธ์ œ๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์Šคํ† ์–ด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์„ค์ •ํ–ˆ๋‹ค๋ฉด ์™œ redux๊ฐ€ undefined ์ƒํƒœ๋กœ ๋ฆฌ๋“€์„œ๋ฅผ ํ‰๊ฐ€ํ•˜๋ ค๊ณ  ํ• ๊นŒ์š”? ๊ทธ๋Ÿฌ๋ฉด ์‹ค์ œ๋กœ ๋ชจ๋“  ๊ฐ์†๊ธฐ๊ฐ€ ์ƒˆ ์ƒํƒœ undefined ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋„Œ์„ผ์Šค์ž…๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์ด๊ฒƒ์€ ์‹คํŒจํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค:

import { combineReducers, createStore } from 'redux';

const configReducer = (config: any, action: any): any =>{
        return config;
}

const customData = (customData: any, action: any): any =>  {
        return customData;
}
const reducers = combineReducers({config: configReducer, customData: customDataReducer})

const defaultConfig = "cool config";
const data = "yieaah some data";

var initialState = {config: defaultConfig, customData: data};
const store = createStore(reducers, initialState) // at this point redux calls all the reducers with 'undefined' state. Why?

@JoseFMP :

์•„, ๋ฌธ์ œ๊ฐ€ ๋ญ”์ง€ ์•Œ ๊ฒƒ ๊ฐ™์•„์š”. ์ด๊ฒƒ์€ combineReducers() ์ž‘๋™ ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

combineReducers ๋Š” ๋‹น์‹ ์ด ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  "์Šฌ๋ผ์ด์Šค ๋ฆฌ๋“€์„œ"๊ฐ€ ๋ช‡ ๊ฐ€์ง€ ๊ทœ์น™์„ ๋”ฐ๋ฅผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ, ๊ฐ์†๊ธฐ๊ฐ€ state === undefined ๋กœ ํ˜ธ์ถœ๋˜๋ฉด _if_ ์ ์ ˆํ•œ ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด combineReducers() ๋Š” ์‹ค์ œ๋กœ (undefined, {type : "SOME_RANDOMIZED_ACTION_TYPE"}) ๋กœ ๊ฐ์†๊ธฐ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ "์‹ค์ œ" ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์†๊ธฐ๋Š” ํ˜„์žฌ ์ „๋‹ฌ๋œ ๊ฒƒ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋Š” ์•„๋ฌด ๊ฒƒ๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, state ๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ _return_ undefined๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ combineReducers() ๋Š” ์˜ˆ์ƒํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊นจ๊ณ  ์žˆ์Œ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

์„ ์–ธ์„ configReducer = (config = {}, action) ๋“ฑ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๊ฒฝ๊ณ ๊ฐ€ ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค.

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ์ด๊ฒƒ์€ ๋ฒ„๊ทธ๊ฐ€ _์•„๋‹™๋‹ˆ๋‹ค_. ์ด๊ฒƒ์€ ํ–‰๋™ ๊ฒ€์ฆ์ž…๋‹ˆ๋‹ค.

Hej @markerikson ์‘๋‹ต
๋ช‡ ๊ฐ€์ง€ ์˜๊ฒฌ:

1) ์•„๋‹ˆ์š”, combineReducers ๊ตญํ•œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. combineReducers ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋‚˜๋งŒ์˜ ๋ฃจํŠธ ๋ฆฌ๋“€์„œ๋ฅผ ๊ตฌํ˜„ํ•ด๋„ ๊ฐ™์€ ์ผ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

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

@JoseFMP : ์•ž์„œ ๋งํ–ˆ๋“ฏ์ด ๋ฌธ์ œ๋ฅผ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•˜๋Š” CodeSandbox๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๊ณ  ์˜ˆ์ƒ๋˜๋Š” ์ผ๊ณผ ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š” ์ผ์„ ์ •ํ™•ํžˆ ์ง€์ ํ•˜๋Š” ์ฃผ์„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๋˜ํ•œ ์ผ๊ด€์„ฑ์ด ์—†๋‹ค๊ณ  ๋Š๋ผ๋Š” ๋ฌธ์„œ ์„น์…˜์„ ์ง€์ ํ•ด ์ฃผ์„ธ์š”.) ๊ทธ๋•Œ๊นŒ์ง€๋Š” Redux๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์˜คํ•ด์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

@markerikson ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
๋ฌธ์„œ ์ •๋ณด:
image

๋”ฐ๋ผ์„œ ๋ฆฌ๋“€์„œ๊ฐ€ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์•ก์…˜์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฉด ๋ฆฌ๋“€์„œ๋Š” ์ด ๋ฆฌ๋“€์„œ์—์„œ ์•ก์…˜์ด ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผํ•œ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

์˜ˆ์ œ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ:

import { createStore } from 'redux';

const configReducer = (config: any, action: any): any =>{
        return config;
}

const customReducer = (customData: any, action: any): any =>  {
        return customData;
}

const reducers = (currentState: IAppState, action: any): IAppState => {

    var appStateToEvaluate: any;
    if (currentState) { //needs to add this to pass the `undefined` check of redux
        appStateToEvaluate = currentState;
    }
    else{
        //why redux is doing this ?!
        appStateToEvaluate = {}
    }
    const newState: IAppState = {
        cvConfig: configReducer(appStateToEvaluate.config, action),
        personalData: customReducer(appStateToEvaluate.customData, action)
    }

    return newState;
}

const defaultConfig = "cool config";
const data = "yieaah some data";

var initialState = {config: defaultConfig, customData: data};
const store = createStore(reducers, initialState) // at this point redux calls all the reducers with 'undefined' state. Why?

@JoseFMP : ์—ฌ๊ธฐ์„œ ๋†“์น˜๊ณ  ์žˆ๋Š” ์ฃผ์š” ์ฐจ์ด์ ์€ ํ•ด๋‹น ์˜ˆ์—์„œ ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๊ฐ€ ES6 ๊ธฐ๋ณธ ์ธ์ˆ˜ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ state ๊ฐ€ undefined ์ธ ๊ฒฝ์šฐ๋ฅผ _์ด๋ฏธ_ ์ฒ˜๋ฆฌํ–ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

function todoApp(state = initialState, action) {

๋”ฐ๋ผ์„œ ํŠœํ† ๋ฆฌ์–ผ์˜ ์กฐ์–ธ์€ ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋“€์„œ๋Š” _์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๊ฐ€ ์ด๋ฏธ ์ฒ˜๋ฆฌ๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ _ ํ•ญ์ƒ ๊ธฐ์กด ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@markerikson
๋‹ต๋ณ€ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํŠœํ† ๋ฆฌ์–ผ์—์„œ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ๋ฐ˜ํ™˜ํ•  ์ผ€์ด์Šค๊ฐ€ ๋ฆฌ๋“€์„œ์—์„œ ๊ธฐ๋ณธ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’์œผ๋กœ ์ง€์ •๋œ ์ผ€์ด์Šค๋ผ๊ณ  ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ์šธ์ž„๊ผด๋กœ ๋งŒ๋“  ๋ฌธ์žฅ์ด ๋งž์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ๊ทธ๊ฑฐ์•ผ. ๋‚ด ๊ด€์‹ฌ์‚ฌ๋Š” ํŠœํ† ๋ฆฌ์–ผ์—์„œ ๋ˆ„๋ฝ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜๋Š” ๋‚ด๊ฐ€ ์ฐพ์ง€ ๋ชปํ–ˆ๊ฑฐ๋‚˜ ๋ชจํ˜ธํ•ฉ๋‹ˆ๋‹ค.

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

๋งˆํฌ ์ง€์›ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋” ํฐ ๋ฌธ์„œ ๊ฐœํŽธ(#2590)์˜ ์ผํ™˜์œผ๋กœ ์ผ๋ถ€ ๋ฌธ๊ตฌ์˜ ๋‹จ์–ด๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

์•„์ง ๋งํฌํ•˜์ง€ ์•Š์€ ๊ฒƒ์ด ๋‹ค์†Œ ๋†€๋ž์ง€๋งŒ ๋ฌธ์„œ์˜ Initializing State ํŽ˜์ด์ง€๋ฅผ ์ฝ๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@markerikson
๊ทธ๋ž˜ ์ •ํ™• ํ•ด. ๋‚˜๋Š” ์ด๋ฏธ ์ดˆ๊ธฐ ์ƒํƒœ์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”(๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ ๋ฏฟ๋Š” ์ด์œ ๋Š” ์ด ๋ฌธ์ œ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๊ณ  ์‚ฌ๋žŒ๋“ค๋„ ์ด ๋ฐฉํ–ฅ์„ ์˜๋ฏธํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค)์€ ์ƒ์ ์„ ์ƒ์„ฑํ•  ๋•Œ "์ดˆ๊ธฐ ์ƒํƒœ"๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์—ฌ์ „ํžˆ "๊ธฐ๋ณธ ์ƒํƒœ"๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ง๊ด€์ ์ด์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์Šฌ๋ผ์ด์Šค ๋ฆฌ๋“€์„œ(๋˜๋Š” ๋ฃจํŠธ ๋ฆฌ๋“€์„œ). ์ฆ‰, ๋งค์šฐ ์ž์ฃผ(๋ฐ˜๋“œ์‹œ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ) ๋™์ผํ•˜๊ฑฐ๋‚˜ ๋งค์šฐ ๊ด€๋ จ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ํ•ญ๋ชฉ์„ ์ •์˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์ง๊ด€์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @ElonXun ๋˜๋Š” @Vittly ๊ฐ€ ์ €์™€ ๊ฐ™์€ ํ˜ผ๋ž€์„ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋‚ด ๋ง์€ Redux์˜ API๊ฐ€ ์•„๋‹ˆ๋ผ ์ˆœ์ „ํžˆ ์ธ๊ฐ„์ ์ธ ๊ด€์ ์—์„œ ์ด ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ Redux์˜ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์ง๊ด€์ ์ธ์ง€์— ๋Œ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰ ๋‹จ๋ฝ์€ redux์˜ API๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ธ๊ฐ„์˜ ๋Š๋‚Œ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๊ณ„ ๊ตฌํ˜„ ๋˜๋Š” ๊ทธ ์ด๋ฉด์˜ ์ด์œ ๋Š” ์™„์ „ํžˆ ์ •๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ API ์†Œ๋น„์ž๋กœ์„œ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฌ๋‚˜ ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ€ ์„ค์ •๋˜๊ณ  ์Šฌ๋ผ์ด์Šค ๋ฆฌ๋“€์„œ ๋˜๋Š” ๋ฃจํŠธ ๋ฆฌ๋“€์„œ๊ฐ€ "๊ธฐ๋ณธ ์ƒํƒœ"๋ฅผ ๊ฐ–๋„๋ก ๊ฐ•์ œํ•˜์ง€ ์•Š๋Š” ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์—ฌ์ „ํžˆ ํ•„์ˆ˜๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ์—์„œ ์œ ์ผํ•œ ๊ธฐ์—ฌ๋Š” ๊ทธ๊ฒƒ์ด ์•ฝ๊ฐ„ ์ง๊ด€์— ๋ฐ˜ํ•˜๋Š” ๋Š๋‚Œ์ด ๋“ ๋‹ค๊ณ  ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ƒฅ.

์ด์ „ ๋ฒ„์ „์—์„œ assertReducerShape ๋ฅผ ํ˜ธ์ถœํ•œ combineReducers ๊ธฐ์–ต๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋“œ์—์„œ undefined ๋Š” ๋‚ด ๊ฐ์†๊ธฐ์˜ ์ž˜๋ชป๋œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด CombineReducers๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. "๋ฆฌ๋“€์„œ๋ฅผ ๊ฒฐํ•ฉ"ํ•˜๊ณ  ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๋ฃจํŠธ ๊ฐ์ฒด๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ ์ด์ƒ์œผ๋กœ ์ง„ํ–‰๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. IMO, ์ง€๊ธˆ์€ ๋„ˆ๋ฌด ๋…๋‹จ์ ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๊ฐœ๋ฐœํ•œ ํ•ต์‹ฌ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ํ•„์š”ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋Š” CombineReducers๋ฅผ ํ•œ๋™์•ˆ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ ๊ทธ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋ž˜ํ•‘ํ•˜๋ ค๊ณ  ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ CombineReducers๊ฐ€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์กฐ๊ฐํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. assertReducerShape ์˜ ๋™์ž‘์€ ๋†€๋ž์Šต๋‹ˆ๋‹ค.

@lukescott : ๊ทธ ์ˆ˜ํ‘œ๋Š” 2015๋…„ 9์›”๋ถ€ํ„ฐ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/reduxjs/redux/commit/a1485f0e30ea0ea5e023a6d0f5947bd56edff7dd

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

๊ตฌ์ฒด์ ์ธ ์˜ˆ๋กœ ๋Š” ์ฒดํฌ ์—†์ด 100์ค„๋กœ ๋œ Dan์˜ ์š”์ง€

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

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

๋‚˜๋Š” ๋‹น์‹ ์ด ๋งํ•˜๋Š” ํ–‰๋™ ๋ณ€ํ™”๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์ธ ์˜ˆ๋ฅผ ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ดˆ๊ธฐํ™” ์ฃผ ๋ฌธ์„œ ํŽ˜์ด์ง€ ์‚ฌ์ด์˜ ์ƒํ˜ธ ์ž‘์šฉ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค preloadedState ๋Œ€ํ•œ ์ธ์ˆ˜ createStore ์˜ state = initialState ๊ฐ์†๊ธฐ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ, ๋ฐ combineReducers() . ์ด๋Š” Dan์ด 2016๋…„ ์ดˆ์— ์ž‘์„ฑํ•œ Stack Overflow ๋‹ต๋ณ€์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ์˜๋ฏธ ์žˆ๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์—†์Šต๋‹ˆ๋‹ค.

@markerikson ๋งž์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” 2.0๊นŒ์ง€ ๋˜๋Œ์•„ ๋ณด์•˜๊ณ  ํ•ญ์ƒ ๊ทธ๋žฌ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋‚ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณต์žก์„ฑ์œผ๋กœ ์ธํ•ด ๋” ๋ช…ํ™•ํ•ด์กŒ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๊ฐ€์ง„ ๋ฌธ์ œ๋Š” ๋‚ด ๊ฐ์†๊ธฐ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

reducer(state: State, action: Action)

์ƒํƒœ๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์•„์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ CombineReducers๋Š” ํ™•์ธ์„ ์œ„ํ•ด reducer(undefined, INIT)๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด ์ฝ”๋“œ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(์„ฑ๊ณตํ•˜๋ฉด ๋‚˜์ค‘์— reducer(initState, INIT)๋ฅผ ํ˜ธ์ถœ - INIT๋ฅผ ๋‘ ๋ฒˆ ํ˜ธ์ถœ).

์ด๊ฒƒ์€ CombineReducers์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ๊ฐ์†๊ธฐ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

reducer(state: State | undefined, action: Action)

๋”ฐ๋ผ์„œ ์ด์ „์—๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ๋‚ด ์ฃผ์žฅ์€ ์ž˜๋ชป๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฌธ์ œ์™€ OP๊ฐ€ ๊ฐ€์ง„ ๋ฌธ์ œ๋Š” ๋™์ผํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ์„ ํƒ์ ์ธ ์ƒํƒœ๋กœ ๊ฐ์†๊ธฐ๋ฅผ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •์˜๋˜์ง€ ์•Š์€ ์ƒํƒœ๊ฐ€ ์˜ˆ์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๊ฐ€ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•ด์•ผ ํ•˜๊ณ  ๋‚ด๊ฐ€ ์ง์ ‘ ๊ตด๋ ค์•ผ ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๋ชจ์–‘์„ ์ฃผ์žฅํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ๋Ÿฐํƒ€์ž„์— ์ด๋ฏธ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ์–‘์„ ์ฃผ์žฅํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์†Œ ๊ณผ๋„ํ•˜๊ณ  ๋น„์ƒ์‚ฐ์ ์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์˜ˆ. ํ•ด๋‹น ๋ฌธ์„œ ํŽ˜์ด์ง€์— ์„ค๋ช…๋œ ๋Œ€๋กœ combineReducers ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ ์Šฌ๋ผ์ด์Šค ๋ฆฌ๋“€์„œ๋Š” ๊ณ ์œ ํ•œ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ฑ…์ž„์ด ์žˆ์œผ๋ฉฐ sliceReducer(undefined, action) ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. combineReducers ์‹œ์ ์—์„œ ์ฝ”๋“œ๊ฐ€ _is_ ๋ฒ„๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ƒ๋œ ๊ณ„์•ฝ์„ ์ค€์ˆ˜ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๋‹ค๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ์ฝ”๋“œ๋Š” ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๊นŒ?

createStore๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  assertReducerShape๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ undefined ๋‚ด ๊ฐ์†๊ธฐ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ€ ๋‚ด ๊ฐ์†๊ธฐ๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

https://github.com/reduxjs/redux/blob/231f0b32641059caab3f98a3e04d3afaad19a7d1/src/combineReducers.js#L68

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

๋‚ด๊ฐ€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์€ assertReducerShape๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„ ์‹œ ์—ฌ๊ธฐ์—์„œ ์ด๋ฏธ undefined ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

https://github.com/reduxjs/redux/blob/231f0b32641059caab3f98a3e04d3afaad19a7d1/src/combineReducers.js#L169

assertReducerShape๋Š” ์ผ์ข…์˜ ์ค‘๋ณต๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ œ ๊ฒฝ์šฐ์—๋Š” ์œ ํ˜• ๋ณด์žฅ์ด ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค... ์ด๊ฒƒ์ด ์ฃผ์žฅํ•˜๋ ค๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๊ทธ๋ ‡๋‹ค๋ฉด ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ TypeScript ์ƒํ˜ธ ์ž‘์šฉ ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ?

์†”์งํžˆ ๋งํ•˜์ž๋ฉด ์ด๋Š” ๊ฒฐ๊ตญ ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์ฐจ์ด์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

combineReducers() ์€ JS๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ๋Ÿฐํƒ€์ž„ ๊ฒ€์‚ฌ๋ฅผ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

TS์—์„œ ์ •์  ๊ฒ€์‚ฌ๋ฅผ ํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ์ž‘์„ฑํ•œ ์„ ์–ธ์ด combineReducers() ์‹ค์ œ ์ž‘๋™ ๋ฐฉ์‹๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์˜๋ฏธ์—์„œ ์Šฌ๋ผ์ด์Šค ๋ฆฌ๋“€์„œ์˜ ์œ ํ˜• ์„ ์–ธ์€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด combineReducers() ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ๋•Œ undefined ๊ฐ€ _can_ ๋ฐ _will_ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

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

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

export default function itemReducer(state = initialState.items | undefined, action){ 
    switch(action.type) 
   { 
         case "LOAD_ITEMS_SUCCESS":
               if(action.items==undefined) { 
                        action.items=[]; 
               }
                return action.items

๋ฆฌ๋“€์„œ๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋นˆ ๋ฐฐ์—ด์„ undefined๋กœ ๋ฐ”๊พธ๋ฉด ๋” ์ด์ƒ ํ•ด๋‹น ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฑด๋ฐฐ!

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