2017-11-15 18 views
2

リアクションルータで区切られたセクションを持つダッシュボードがあります。reduxの初期状態とレデューサーでネストされたオブジェクトを使用する

セクションは以下のとおりです。

  • カテゴリー

  • 試験

  • レポート

試験セクションを見てみましょう。この状態を初期状態とする。

{ 
     ID: null,   
     RandomizeQuestions: false, 
     RandomizeAnswers: false, 
     Pages: [ 
      { 
       ID: 1, 
       Title: 'Page one',     
       Blocks: [ 
        { 
         ID: 1, 
         Title: 'Block One',       
         Questions: [ 
          { 
           ID: 1,         
           Title: "Quesiton title is here", 
           Answers: [ 
            { 
             ID: 1, 
             Title: "Answer 1" 
            }, 
            { 
             ID: 2, 
             Title: "Answer 2" 
            } 
           ] 
          } 
         ] 
        } 
       ] 
      } 
     ] 
    } 

私はreduxを使用するときに状態を平坦化し、正規化する必要があることを知っています。それは私の正確な問題です。私の状態を正常化しようとすると、次のようになります。

{ 
Exam: { 
    ID: null,  
    RandomizeQuestions: false, 
    RandomizeAnswers: false 
}, 
ExamPages: [ 
    { 
     ExamId: 1, 
     ID: 1, 
     Title: 'Page One'   
    } 
], 
ExamBlocks: [ 
    { 
     ID: 1, 
     Title: 'The New Block',    
     Questions: [] 
    } 
], 
ExamQuestions: [], 
ExamAnswers: [] 
} 

それは問題ないと思います。しかし、他のセクションに起こったときは?

カテゴリは、大きすぎると報告する独自の状態もあります。

(そこに私は言及しなかった他のセクションがあります)、その後、私のcombineReducerは次のようになり、次のようになります。

import {combineReducers} from 'redux' 
import Exam from './redc.exams.jsx' 
import ExamBlocks from './redc.blocks.jsx' 

const rootReducer = combineReducers({ 
    Exam, 
    ExamBlocks 
}) 

export default rootReducer 

と私は、そのオブジェクト内のすべてのアレイの減速を持っている必要があり、もちろん。

const initialState = { 
    Exams: { 
     Blocks: [], 
     Questions: [], 
     Answers: [] 
    }, 
    Categories: { 
     Menus: [], 
     Users: [] 
    }, 
    Report: { 
     MainReports: [], 
     SideReports: [] 
    } 
} 

が、私はそれらのそれぞれに別々の減速を持つようにしたいことを忘れないでください:

ので、私の主な質問は、私がでLESTこのような構造を持つことができる方法です。私は@Tomフェネシュを試してみました ブロックのための減速、質問のための減速のように...

UPDATE#1

は答えに言ったが、最終的なcombineReducers前に減速を組み合わせることはできません。 今、私のルート減速されるが、次のようになります。

import {combineReducers} from 'redux' 

//Exams 
import Exams from './ExamsReducers/redc.exams.jsx' 
import Blocks from './ExamsReducers/redc.blocks.jsx' 

//Categories 
import Categories from './CategoriesReducers/redc.categories.jsx' 

const rootReducer = combineReducers({ 
     Exams, 
     Categories, 
     Blocks, 
}) 

export default rootReducer 

私は彼が言っていることとし、ここにしようとした私のコードは、変更後です:

import {combineReducers} from 'redux' 

//Exams 
import Exams from './ExamsReducers/redc.exams.jsx' 
import Blocks from './ExamsReducers/redc.blocks.jsx' 

//Categories 
import Categories from './CategoriesReducers/redc.categories.jsx' 

const examRedc = combineReducers(Exams,Blocks) 
const catsRedc = combineReducers(Categories) 

const rootReducer = combineReducers(examRedc, catsRedc) 

export default rootReducer 

私はこのエラーを取得:

Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers. 

と、このようなコンポーネントのいずれかで状態を記録すると、

var mapDispatchToProps = function (dispatch) { 
    return { 
     AddBlock: function() { 
      dispatch(addBlock()); 
     } 
    } 
}; 

const mapStateToProps = function (state) { 
    console.log(state); //////HERE 
    return {Blocks: state.Blocks}; 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Blocks) 

私は最終的には望んでいないこの状態になります。

final output

答えて

2

のような減速構造を入れ子にしていることができます。さて、代わりにネストされたオブジェクトを格納する、私たちは所有権を追跡するために自分のIDを格納し

{ 
    Exams: { 
     [ID]: { 
      ID: string, 
      RandomizeQuestions: boolean, 
      RandomizeAnswers: boolean, 
      Blocks: string[] // array of block IDs 
     } 
    } 
    Blocks: { 
     [ID]: { 
      ID: string, 
      Title: string, 
      Questions: string[] // array of question IDs 
     } 
    }, 
    Questions: // etc. 
} 

:私はトップレベルでこのような何かを示唆しています。

この状態は、使用して作成されます:あなたはセクションに全体の状態を分割したい場合、あなたはこのようなものを使用することができ

state = combineReducers({ 
    examsReducer, 
    blocksReducer, 
    // ...more reducers 
}) 

const examStuff = combineReducers({ 
    examsReducer, 
    blocksReducer, 
    // ... 
}); 

const categoryStuff = combineReducers({ 
    categoriesReducer, 
    menusReducer, 
    // ... 
}); 

const state = combineReducers({ 
    examStuff, 
    categoryStuff 
}); 

その後の状態は次のようになります。

{ 
    examStuff: {} // the object defined at the top of question, 
    categoryStuff: {}, 
    otherStuff: {} 
} 
+0

このようなことをしたいのですか? 'ブロック:[ { ID:文字列、 ExamId:文字列、 タイトル:文字列、 } ]' 代わりにあなたはあなたのアプリケーションで、より理にかなっているものは何でもする必要があり –

+0

親にそれらの値を格納します。特定のブロックの検査を簡単に検索できるようにすると便利な場合は、IDを別の方法で保存することが理にかなっています。ところで、配列ではなくオブジェクトを使用して、IDでブロックを簡単に参照できるようにします。 –

+0

私はすでにそれを試みました。あなた自身でこれを試してください。エラーが表示されます。 –

1

あなたは、私がExamsの内側BlocksQuestionsAnswersを持ってする必要はないと思う

// block_reducer.js 
export const reducer = (state = [], action) => { 
    switch (action.type) { 
    case BLOCK_ACTION: 
    return [{a:1}, {b:2}] 
} 
    return state 
} 


// exam_reducer.js 
import {combineReducers} from 'redux' 
import {reducer as BlockReducer} from './block_reducer' 

export const reducer = combineReducers({ 
    Blocks: BlockReducer, 
    Sections: ....., 
    Answers: ....... 
}) 

// root_reducer.js 
import {combineReducers} from 'redux' 
import {reducer as examReducers} from './exam_reducers' 

export const reducer = combineReducers({ 
    Exams: examReducers, 
    Categories: ....., 
    Report: ...... 
}) 
関連する問題