我试图找到理想的方法来更新状态树上的几个顶级字段,同时仍保持拆分缩减器。
这是我提出的一个简单的解决方案。
var state = {
fileOrder: [0],
files: {
0:{
id: 0,
name: 'asdf'
}
}
};
function handleAddFile(state, action) {
return {...state, ...{[action.id]:{id: action.id, name: action.name}}};
};
function addFileOrder(state, action) {
return [...state, action.id];
}
// Adding a file should create a new file, and add its id to the fileOrder array.
function addFile(state, action) {
let id = Math.max.apply(this, Object.keys(state.files)) + 1;
return {
...state,
fileOrder: addFileOrder(state.fileOrder, {id}),
files: handleAddFile(state.files, {id, name: action.name})
};
}
目前,我可以发送单个操作{type: ADD_FILE, fileName: 'x'}
,然后addFile
在内部创建一个操作,以便发送到addFileOrder
和addFile
。
我很好奇是否认为这是下列任何一种方法的更好方法。
而是发送两个动作,一个用于添加文件,然后获取它的ID并使用id发送ADD_TO_FILE_ORDER
动作。
或消防和{type: ADD_FILE, name: 'x', id: 1}
之类的操作,而不是允许addFile
计算新ID。这将允许我使用combineReducers
并过滤操作类型。
这个例子可能很简单,但我的实际状态树有点复杂,每个文件的添加也需要添加到其他实体。
对于某些其他上下文,更完整的状态树将如下所示。
{
"fileOrder": [0]
"entities": {
"files": {
0: {
id: 0,
name: 'hand.png'
}
},
"animations": {
0: {
id: 0,
name: "Base",
frames: [0]
}
},
"frames": {
0: {
id: 0,
duration: 500,
fileFrames: [0]
}
},
"fileFrames": {
0: {
id: 0,
file: 0,
top: 0,
left: 0,
visible: true
}
}
}
}
添加文件需要:
最后两点让我想知道我是否能够使用combineReducers。
答案 0 :(得分:7)
我最终找到了解决这个问题的非常简单的方法。
文档中的这两个块在功能上都是一样的。
opacity:1!important
我最后调整了第二个块,并且总是传递我的全局状态树。只要沿途没有任何编辑状态,所有减速器都可以正常工作。
const reducer = combineReducers({
a: doSomethingWithA,
b: processB,
c: c
});
// This is functionally equivalent.
function reducer(state, action) {
return {
a: doSomethingWithA(state.a, action),
b: processB(state.b, action),
c: c(state.c, action)
};
}
答案 1 :(得分:2)
以作者的解决方案为基础:
我一直有同样的问题,我需要(只是一点点)访问我的减速机部分状态。我认为这个解决方案可以在实践中发挥作用,如果你努力不改变除了标志或计数器等单一价值之外的任何东西。
如果其他开发人员没有像他们的代码那样保留,那么它的杂质就会变得疯狂。想象一下,如果开始改变b和c的状态部分,b改变a和c的部分,等等会发生什么。
您可能会考虑缩小杂质的表面积,如下所示:
function reducer(state, action) {
return {
a: doSomethingWithA(state.a, action, state.globals),
b: processB(state.b, action, state.globals),
c: c(state.c, action, state.globals)
};
}