2017-11-15 3 views
2

Ich habe Dashboard, die eine Abschnitte haben, die durch React-Router getrennt ist.Verwenden verschachtelter Objekte in redux Ausgangszustand und Reduzierungen

Abschnitte sind:

  • Kategorien

  • Prüfungen

  • Berichte

Werfen wir einen Blick auf den Abschnitt Prüfung. wir haben diesen Zustand als Ausgangszustand.

{ 
     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" 
            } 
           ] 
          } 
         ] 
        } 
       ] 
      } 
     ] 
    } 

Ich weiß, dass der Zustand flach und normalisiert werden sollte, wenn ich Redux verwende. aber das ist mein genaues Problem. wenn ich versuche, meinen Zustand zu normalisieren sollte es so sein:

{ 
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: [] 
} 

lässt vermuten, dass es ok und ich habe gewohnt Problem mit ihm. aber wenn es mit den anderen Abschnitten passiert?

Kategorien haben eigene Zustände, die auch groß sind und melden. (Es gibt auch andere Abschnitt, die ich nicht erwähnt)

und dann würde mein combineReducer sein sieht wie folgt aus:

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

const rootReducer = combineReducers({ 
    Exam, 
    ExamBlocks 
}) 

export default rootReducer 

und natürlich sollte ich ein Reduktionsmittel für die in diesem Objekt jedes Array.

so meine wichtigste Frage ist, wie kann ich damit nicht diese Struktur haben:

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

erinnern, dass ich getrennte Reduzierungen für jeden von ihnen haben wollen. ein Minderer für Blöcke, Druckminderer für Fragen und so weiter ...

UPDATE # 1

Ich versuchte @ Tom Fenech in den Antworten, sagte aber nicht kombinieren Reduzierungen vor der endgültigen combineReducers. jetzt ist meine Wurzelreduzierer sieht wie folgt aus:

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 

ich versuchte, was er sagt, und hier mein Code nach den Änderungen ist:

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 

bekomme ich diesen Fehler:

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

und wenn ich den Zustand in einer der Komponenten wie diese

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) 
0 protokollieren

Ich bekomme diesen Zustand, der ist nicht was ich will endlich.

final output

Antwort

2

Ich glaube nicht, dass es erforderlich Blocks, Questions und Answers innerhalb von Exams zu haben ist. Ich würde so etwas wie dies auf der obersten Ebene vorschlagen:

{ 
    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. 
} 

Statt nun die verschachtelten Objekte zu speichern, speichern wir nur ihre ID Spur Eigentum zu halten.

würde Dieser Zustand erstellt werden:

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

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

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

Dann würde Zustand sein:

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

Wenn Sie den Gesamtzustand in Abschnitte geteilt werden soll, so etwas wie dieses Sie nutzen könnten

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

ist es in Ordnung, wenn ich so etwas haben möchte? 'Blöcke: [ { ID: string, ExamId: string, Titel: string, } ]' stattdessen diese Werte in den übergeordneten das Speichern –

+0

Sie sollten mehr Sinn in der Anwendung macht alles tun, was. Wenn es sinnvoller ist, Prüfungen für einen bestimmten Block einfach nachschlagen zu können, ist es sinnvoll, die IDs anders herum zu speichern. Übrigens würde ich eher ein Objekt als ein Array verwenden, um das Nachschlagen von Blöcken nach ID zu erleichtern. –

+0

das habe ich schon ausprobiert. Bitte versuchen Sie es selbst und Sie werden die Fehler sehen. –

1

Sie verschachtelt haben, können Minderer Struktur wie

// 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: ...... 
}) 
Verwandte Themen