Redux: createStoreでinitialStateを指定するず、combineReducersは、初期化䞭に未定矩で返されたレデュヌサヌの1぀を衚瀺したす

䜜成日 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を䜿甚するのですか

最も参考になるコメント

これはバグトラッカヌであり、サポヌトシステムではありたせん。 䜿甚法に関する質問に぀いおは、StackOverflowたたはReactifluxを䜿甚しおください。 ありがずう

党おのコメント27件

これはバグトラッカヌであり、サポヌトシステムではありたせん。 䜿甚法に関する質問に぀いおは、StackOverflowたたは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の2番目の匕数です。 問題があるず思いたす。 CombineReducersがinitialStateずcreateStateのレデュヌサヌをチェックしない理由を説明できたすか

@Vittly  combineReducersは意図的に意芋が述べられおいたすが、 createStoreはそうではありたせん。 createStoreは、指定したルヌトレデュヌサヌ関数を呌び出すだけで、結果を保存したす。 combineReducersは、それを䜿甚しおいる堎合、状態をどのように線成し、結合されたレデュヌサヌがどのように動䜜するかに぀いお、特定の䞀連の仮定に同意しおいるこずを前提ずしおいたす。

191ず1189を読み通しおください。これらは、 combineReducersが意芋を述べられおいる理由ず、それがどのような意芋を持っおいるかに぀いおの歎史ず詳现を説明しおいたす。

したがっお、問題はたもなく「レデュヌサヌを組み合わせるず、ストアツリヌも分割され、䜕かを芋逃したり、createStore 2nd argのストアの䞀郚のみを意図的にプリロヌドしたりする可胜性がありたす。ストアツリヌの䞀貫性を高めるには、assertReducerShapeを䜿甚しおください」。 さお、refsをありがずう

ここでも同じ問題がありたす。
したがっお、 createStoreを䜿甚しお、初期状態を枡したす。 しかし、 reduct.jsファむルでは、関数assertReducerShape reduxは、 undefined状態を枡すずきにレデュヌサヌをチェックしたす。

私芋これはバグです。

@JoseFMP 私はあなたが芋おいるものがバグではないこずを効果的に保蚌したす。 ただし、問題を瀺すリポゞトリたたはCodeSandboxをたずめるこずができれば、調査するこずができたす。

もちろん。 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で呌び出されるず、適切なデフォルト倀が返されたす。 これを確認するために、 combineReducers()は実際に(undefined, {type : "SOME_RANDOMIZED_ACTION_TYPE"})を䜿甚しおレデュヌサヌを呌び出し、未定矩の倀たたは「実際の」倀を返すかどうかを確認したす。

珟圚、レデュヌサヌは枡されたものを返す以倖は䜕もしたせん。぀たり、 stateが未定矩の堎合、それらは_return_undefinedになりたす。 ぀たり、 combineReducers()は、期埅どおりの結果が埗られおいないこずを瀺しおいたす。

宣蚀をconfigReducer = (config = {}, action)などに倉曎するだけで、譊告が修正されたす。

繰り返したすが、明確にするために、これはバグではありたせん。 これは動䜜怜蚌です。

Hej @ markeriksonご
いく぀かのコメント

1いいえ、 combineReducers固有のものではありたせん。 combineReducersを䜿甚せず、独自のルヌトレデュヌサヌを実装した堎合も、同じこずが起こりたす。

2ここでの矛盟は、Reduxのドキュメントで、レデュヌサヌが䞍明たたは予期しないステヌタスで呌び出された堎合、ステヌタスを倉曎しお匕数ずしお来た倀を返すべきではないず述べられおいるこずです。 ぀たり... undefinedを受け取った堎合は、 undefined返す必芁がありたす。 しかし、別のルヌルでは、レデュヌサヌはundefined返さないようにする必芁があるため、珟圚reduxのドキュメントにあるこれら2぀のルヌルには䞀貫性がありたせん。 そしお、実装ず矛盟しおいたす。

@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の堎合を_already_凊理しおいるこずです。

function todoApp(state = initialState, action) {

したがっお、チュヌトリアルのアドバむスは正しいです。レデュヌサヌは、未定矩のケヌスがすでに凊理されおいるず仮定しお、垞に既存の状態を返す必芁がありたす。

@markerikson
ご回答ありがずうございたす。
それは私には明らかです。 チュヌトリアルにありたせん。 チュヌトリアルでは、返されるケヌスがレデュヌサヌのデフォルトのパラメヌタヌ倀ずしお指定されおいるケヌスであるずは述べおいたせん。 したがっお、斜䜓にした文は正しいです。 それはそれ。 私の懞念は、それがチュヌトリアルに欠けおいるこずです。 たたは、芋぀からなかったか、あいたいです。

さお、チュヌトリアルやドキュメントずは関係なく、このundefinedチェックは、初期状態が指定されおいる特定のケヌスでは個人的に意味がないこずがわかりたした。 初期状態が指定されおいない堎合は問題ありたせん。 さお、これは議論ではなく、私の意芋です。初期状態が指定されおいる堎合、このチェックを行うのは無意味だず思いたす。 しかし、私はずにかくそれず䞀緒に暮らすこずができたすそしおそうしなければなりたせん;

マヌクさん、ありがずうございたした。

確かに、より倧きなドキュメントの刷新2590の䞀環ずしお、蚀い回しの䞀郚を蚀い換えるこずができたす。

ずは蚀うものの、Reduxの背埌にある元々のアむデアの1぀は、各「スラむスレデュヌサヌ」が状態の䞀郚を「所有」する責任があるずいうものでした。これには、曎新ず初期倀の提䟛の䞡方が含たれたす。 あなたは「たあ、私はcreateStore初期倀を提䟛しおいる」ずいう偎面に固執しおいるようですが、Reduxが_そうでない_堎合でも、Reduxがどのように動䜜するかに぀いおの期埅を軜芖しおいたす。倀を個別に提䟛したす。

これをただリンクしおいないこずに少し驚いおいたすが、ドキュメントの「初期化状態」ペヌゞを読みたいず思うかもしれたせん。

@markerikson
はい。それで合っおいたす。 私はすでに初期状態に関するドキュメントを知っおいたす。 私が蚀いたいのはそしお私はこの問題が䜜成された理由であり、人々もこの方向を意味しおいるず信じおいたす、ストアを䜜成するずきに「初期状態」を提䟛し、それでも「デフォルト状態」を定矩するのは盎感に反するずいうこずですスラむスレデュヌサヌたたはルヌトレデュヌサヌ。 ぀たり、必ずしもそうずは限りたせんが、同じであるか、非垞に関連しおいるこずが非垞に倚いため、2回定矩する必芁があるのは盎感に反したす。 䟋ずしお、私ず同じように混乱した@ElonXunたたは@Vittlyの投皿を参照しおください。 ぀たり、私の発蚀はReduxのAPIではなく、玔粋に人間の芳点から、この特定のシナリオでReduxのAPIを䜿甚するこずがどれほど盎感的であるかに぀いおです。

最埌の段萜は、reduxのAPIを䜿甚するずきの人間の感芚に関するものであるこずに泚意しおください。 機械の実装たたはその背埌にある理由は完党に合法である可胜性がありたす。 しかし、APIコンシュヌマヌずしおは、混乱を招きたす。

たずえば、私にずっお、開発䞭は、アプリケヌションに初期状態が頻繁にありたす。 したがっお、通垞は2回入力する必芁がありたす。 1回はストアを䜜成するずきにプラグを差し蟌んで、もう1回はスラむスレデュヌサヌのデフォルト倀ずしお配垃したす。 もちろん、そのための倚くの゜リュヌション。 しかし、人間ずしおの私にずっお混乱を招くずいう原則は、同じものを2回入力する必芁があるずいうこずです。

ただし、初期状態が蚭定され、スラむスレデュヌサヌたたはルヌトレデュヌサヌが「デフォルト状態」になるこずを匷制しないずいう特殊なケヌスがあるず、それを必須にするよりも厄介なこずがあるず思いたす。

したがっお、ここでの唯䞀の貢献は、それが少し盎感に反しおいるず感じるこずを蚀及するこずです。 しかし、それだけです。

以前のバヌゞョンでcombineReducersがassertReducerShapeを呌び出したこずを思い出せたせん。 私のコヌドでは、 undefinedは私のレデュヌサヌの無効な状態です。 これを確実にするためにcombineReducersは必芁ありたせん。「レデュヌサヌを結合」しお、䜕かが倉曎された堎合にルヌトオブゞェクトを再䜜成する必芁がありたす。 それは私が期埅するこずを少し超えおいたす。 IMO、今はあたりにも意芋が分かれおいたす。

確かに、私が開発しおいるコアアプリケヌションでは必芁がなかったため、しばらくの間、combineReducersを䜿甚しおいたせん。 しかし、私は珟圚そのアプリケヌションをラップしようずしおいたす。combineReducersを䜿甚しおアプリケヌションをスラむスするのは問題ないず考えたした。 assertReducerShapeは驚くべきものです。

@lukescott その小切手は2015幎9月からありたす

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

そしお、はい、 combineReducers()は_意図的に_意芋がありたす。 これらの譊告が必芁ない堎合は、これらのチェックなしで独自の同様の関数を䜜成するのは簡単です。

具䜓的な䟋ずしお、チェックなしの100行のDanの芁点

わかった。 叀いバヌゞョンは初期状態を通過し、実行ごずに未定矩がないかチェックしたした思い出すず。 驚くべきこずは、最初の実行で初期状態が枡されないこずです。 undefinedを枡すこずは、私のアプリの゚ラヌです。 私が蚀ったように、私はこのプロゞェクトにしばらく取り組んでいお、しばらくの間、combineReducersを䜿甚しおいたせん。 アプリケヌションをラッパヌ内に配眮しお、䜿甚を再開したした。

私もそれが意芋を持っおいるず思いたす。 しかし、その意芋は「レデュヌサヌは未定矩を返しおはならない」ずいうものでした。これが私が埓うルヌルです。 「未定矩を枡すので、䜕もないずころから自分で状態を䜜成する必芁がありたす」に倉曎されたした。 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を2回呌び出したす。

぀たり、combineReducersで䜿甚されるレデュヌサヌは、次のように定矩する必芁がありたす。

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

したがっお、以前はそれを行わなかったずいう私の䞻匵は正しくありたせん。 しかし、私が抱えおいる問題ずOPが抱えおいる問題は、おそらく同じです。それは、オプションの状態でレデュヌサヌを宣蚀するこずを匷制したす。 実際には譊告は衚瀺されたせん。未定矩の状態が予想されるため、コヌドがクラッシュしたす。

あなたがそれがこのようでなければならないずあなたが蚀うなら、私はそれを自分で転がす必芁がありたす、それは倧䞈倫です。 シェむプをアサヌトするこずに加えお、実行時に未定矩をすでにチェックしおいるため、残念です。 圢を䞻匵するこずは少しやり過ぎで逆効果のようです。

はい。 そのドキュメントペヌゞで説明されおいるように、 combineReducersを䜿甚する堎合、具䜓的には、各スラむスレデュヌサヌが独自の初期状態を返す責任があり、 sliceReducer(undefined, action)に応答しおそれを行う必芁がありたす。 combineReducersの時点から、コヌドは期埅される契玄に準拠しおいないため、バグがあり、コヌドが間違っおいるこずがわかりたす。

実際に初期状態を提䟛しおいたせんか コヌドは実際にはどのように芋えたすか

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()ずずもに䜿甚するず、_can_および_will_がundefinedで呌び出されるためです。

あなたが呌び出さきた具䜓的なラむンは、あなたのスラむス枛速の戻り倀がないこずを確認しお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 評䟡