我为Redux编写Reducer会遇到困难。具体来说,我最终在.map,.slice等中包含了很多我的状态操作。当我的状态对象的结构变大时,reducers变得难以阅读,函数包含函数等。
var path = require('immutable-path').path;
let state = {
level1: {
level21: {
level3: 3
},
level22: [{
id: 1,
val: 1
}, {
id: 2,
val: 2
}]
}
};
let newState = path(state, 'level1.level22[id=1].val', x => x + 10);
它给出一个新状态,使原始状态保持不变。未修改的对象和数组的引用保持不变(===比较为真)。
有人能告诉我,如果我错过了使用es6语法执行相同结果的更简单方法吗?或者另一个更好的社区维护lib以获得相同的好处?
感谢您的时间和专业知识。
答案 0 :(得分:0)
我建议将你的减速机分解成更小的功能。
下面是四个函数,每个函数依次处理状态的一小部分。 (虽然在每种情况下第一个参数都称为状态,但每次都不同)。但是,行动始终是一样的。
我还没有检查此代码的正确性,但我希望你明白这一点。
function reducerTop(state, action) {
switch (action.type) {
case SET_VAL:
return Object.assign({}, state, {
[action.topLevel]: reducerNext(state[action.topLevel], action);
});
}
return state;
}
function reducerNext(state, action) {
switch (action.type) {
case SET_VAL:
return Object.assign({}, state, {
[action.nextLevel]: reducerArray(state[action.nextLevel], action);
});
}
return state;
}
function reducerArray(state, action) {
switch (action.type) {
case SET_VAL:
const index = state.findIndex((item) => item.id === action.id);
if (index > -1) {
return [
...state.slice(0, index),
reducerFinal(state[index], action),
...state.slice(index + 1)
];
}
}
return state;
}
function reducerFinal(state, action) {
switch (action.type) {
case SET_VAL:
return Object.assign({}, state, {
value: action.value
});
}
return state;
}
答案 1 :(得分:0)
我认为这是redux本身的一个问题 - 它太低级了,有些东西(例如嵌套更新)应该更容易。此外,我相信将所有业务逻辑都放入动作创建者中是没有问题的,并且内部reducers只是更新我们的状态(并在需要时执行嵌套更新)。
从我的观点来看,另一个不必要的事情 - 常数。我们通常有一些所有redux实体的对象(例如,reducers),我认为它应该足以找出所有需要的常量。
有了这个想法,我编写了一个库redux-tiles,它完全正确 - 基于给定的类型,它创建常量,处理异步函数,并为您创建reducer。因此,典型的API请求如下所示:
import { createTile } from 'redux-tiles';
const requestTile = createTile({
type: ['api', 'request'],
fn: ({ api, params }) => api.get('/items', params),
});
它将创建所有常量,减速器,还可以处理故障,成功和加载状态。您可以使用redux-tiles here查看完整的HN API示例。您可能会发现嵌套,它将自动更新所有内容,您只需要返回一组值来嵌套。