2016-08-04 21 views
2

Reduxを使って店舗を管理するReactJsアプリがあります。私の状態は複雑なjsonであり、そのフィールドは変更可能です。私がレデューサーを開始するとき、サーバからコンテンツをフェッチする前にそれにアクセスするとき、初期状態を指定する必要があります。私は 'undefined'エラーを受け取ります。以下は、例です reduxで反応しない初期状態は反応しません

fetchContent() doesntのは、この時点で呼び出されているように見えるので、初めてのコンポーネントを初期化は、state.reducer1.a.b.cが未定義スロー今

//Test.jsx 
 
class Test extends React.Component{ 
 
    componentWillMount(){ 
 
     fetchContent({ 
 
     type: SET_CONTENT 
 
     }); 
 
    } 
 
    render(){ 
 
     return(
 
     <div> {this.props.header} </div> 
 
    ) 
 
    } 
 
    mapStateToProps(state){ 
 
     return{ 
 
     header: state.reducer1.a.b.c 
 
     } 
 
    } 
 
} 
 
export default (mapStateToProps)(Test); 
 

 

 
//reducer1.js 
 
export default function reducer1(state = {}, action = {}) { 
 
    switch (action.type) { 
 
    case SET_CONTENT: 
 
     return Object.assign({}, action.data); 
 
    default: 
 
     return state; 
 
    } 
 
} 
 
    
 
//reducer2.js 
 
export default function reducer2(state = {}, action = {}) { 
 
    switch (action.type) { 
 
    case SET_SOMETHING_ELSE: 
 
     return Object.assign({}, action.data); 
 
    default: 
 
     return state; 
 
    } 
 
} 
 
    
 
//CombinedReducer.js 
 
export default combinedReducers(Object.assign({}, {reducer1}, {reducer2}))

私の質問はどのように私はこの問題を解決するのですか?減速機の初期状態を唯一のオプションに指定していますか?以下、

//reducer1.js 
 
export default function reducer1(state = { a: { b: { c: "somedata"}}}, action = {}) { 
 
    switch (action.type) { 
 
    case SET_CONTENT: 
 
     return Object.assign({}, action.data); 
 
    default: 
 
     return state; 
 
    } 
 
}

答えて

0

のようにあなたことが、あなたはまた、単に最初のキーの存在を確認するためにあなたのmapState機能を更新することができます行うことができます。

function mapStateToProps(state){ 
    return{ 
    header: state.reducer1.a ? state.reducer1.a.b.c : <div>Loading..</div> 
    } 
} 

また、それはあなたがconnectないコンポーネントに固有に渡す機能だと私は、あなたがクラス定義のmapStateToProps外を持っていることを意味と仮定します、最後

class C { 
    ... 
} 

function mapStateToProps (state) {} 

connect(mapStateToProps)(C) 

あなたがディスパッチが欠落していますfetchContentに電話しますか?これはredux-thunkを使っていますか?

+0

私が行ったような状態をlnitializeまたは状態からのデータアクセスのレベルごとにヌルチェックを行うのいずれかの場合だけそう可能な解決策! 機能が外にあると思われていました。私はこれをすぐに書きましたので、正しく機能していませんでした。もちろん、fetchContentは内部的にディスパッチを呼び出すアクション作成者の関数です。 – user3807940

+0

あなたの期待が何か、あなたのためのヌルチェックを行うための何かのためにはわからないのですか?実際には、a)predataとb)のデータをチェックする2つの状態があります。これは、「すべてのレベルのデータアクセス」ではなく、ただ1つのヌルチェックです。 – azium

0

ほとんどの場合、すべての応答データをレデューサーに保存しないでください。あなたの状態階層はJSONレスポンスの階層を繰り返すべきではありません。

それは私はよりシンプルな減速にのみc変数を格納します:

//reducer1.js 

export default function reducer1(state = { c: undefined }, action) { 
    switch (action.type) { 
    case SET_CONTENT: 
     return Object.assign({}, state, { c: action.data.a.b.c }); 
    default: 
     return state; 
    } 
} 

をまた、あなたのコード内のいくつかのミスがあります:

機能は、クラス の外で定義されなければならない
  • mapStateToProps
  • fetchContent関数を直接呼び出す代わりに、その結​​果をディスパッチする必要があります。
// Test.jsx 

class Test extends React.Component{ 
    componentWillMount(){ 
    dispatch(fetchContent({ 
     type: SET_CONTENT 
    })); 
    } 

    render() { 
    const { header } = this.props; 
    return header ? (
     <div>{header}</div> 
    ) : (
     <div>Loading...</div> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
    header: state.reducer1.c 
    } 
} 

export default (mapStateToProps)(Test); 
+0

これは、レビュアーストアがシンプルなjsonを保存する必要があることを意味しますか?サーバーからの応答が複雑で深くネストされたjsonであっても、それらをredux-storeに格納する前に、単純な1レベルjsonに変換する必要がありますか? また、コードミスに関しては、タイプミスのエラーでした。私はクラス定義の外にmapStateToPropsを持っていました。私のfetchContentは、内部的にディスパッチを使用する私のアクションクリエータの1つの関数です:) – user3807940

+0

@user3807940、状況によって異なります。サーバーからjsonを深く入れ子にしているなら、 'normalizr'パッケージの使用を検討してください。ディープネストされたjsonを1レベルのデータに変換するために使用されます。 – 1ven

+0

ああ、クール、前にnormalizrについて聞いたことがありますが、それを試みたことはありません。その時それを叫ぶだろう!返信いただきありがとうございます:) – user3807940

関連する問題