我的仪表板有一个由react-router分隔的部分。
部分是:
分类
考试
报告
让我们来看看考试部分。我们将这种状态作为初始状态。
{
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
当然我应该为该对象中的每个数组都有一个reducer。
所以我的主要问题是我怎么能有这种结构:
const initialState = {
Exams: {
Blocks: [],
Questions: [],
Answers: []
},
Categories: {
Menus: [],
Users: []
},
Report: {
MainReports: [],
SideReports: []
}
}
请记住,我希望每个都有单独的减速器。 块的减速器,问题的减速器等......
我试过@Tom Fenech在答案中说但是在最终的combineReducers之前无法组合减速器。 现在我的root reducers看起来像这样:
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)
我得到的这个状态最终不是我想要的。
答案 0 :(得分:2)
我认为Blocks
内部不需要Questions
,Answers
和Exams
。我会在顶层建议这样的事情:
{
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.
}
现在,我们不是存储嵌套对象,而是存储他们的ID以跟踪所有权。
此状态将使用:
创建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: {}
}
答案 1 :(得分:1)
您可以使用嵌套的reducer结构,如
// 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: ......
})