我正在尝试找出更新状态树上几个顶级字段的理想方法,同时仍然保持拆分缩减器.
这是我提出的一个简单的解决方案.
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})
};
}
Run Code Online (Sandbox Code Playgroud)
目前我能够发送一个动作{type: ADD_FILE, fileName: 'x'},然后addFile在内部创建一个动作发送到addFileOrder和addFile.
我很好奇它是否被认为是更好的方法来做下面的任何一个.
而是发送两个动作,一个用于添加文件,然后获取它的id并发送ADD_TO_FILE_ORDER带有id 的动作.或消防和动作{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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
添加文件需要:
最后两点让我想知道我是否能够使用combineReducers.
我最终找到了解决这个问题的简单方法.
文档中的这两个块在功能上都是相同的.
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)
};
}
Run Code Online (Sandbox Code Playgroud)
我最后调整了第二个块,并且总是传递我的全局状态树.只要沿途没有任何编辑状态,所有减速器都可以正常工作.
// Simple change to pass the entire state to each reducer.
// You have to be extra careful to keep state immutable here.
function reducer(state, action) {
return {
a: doSomethingWithA(state.a, action, state),
b: processB(state.b, action, state),
c: c(state.c, action, state)
};
}
Run Code Online (Sandbox Code Playgroud)