有时减速机会变得很乱:
const initialState = {
notificationBar: {
open: false,
},
};
export default function (state = initialState, action) {
switch (action.type) {
case actions.LAYOUT_NOTIFICATIONBAR_OPEN:
return Object.assign({}, state, {
// TODO: Find a cleaner way to do this!
notificationBar: Object.assign({}, state.notificationBar, {
open: true,
}),
});
default:
return state;
}
}有什么更简洁的方法吗?
发布于 2016-02-24 02:35:14
UPD:它现在是ES2018的一部分
它可能会通过一个然而属性扩展了语法略有改进。
return {
...state,
notificationBar: {
...state.notificationBar,
open: true,
},
};发布于 2016-02-24 02:56:20
虽然可以使用spread操作符,但是还有很多其他方法可以实现相同的结果,甚至不需要将来的JS编译器来实现非标准化的特性。以下是一些没有特定顺序的其他选项。
返回文字
如果您确信您的状态不会增长,那么只需将整个新状态作为文字返回即可。
return {
notificationBar: {
open: true
}
}然而,这并不经常是合适的,因为你的状态不太可能如此简单。
联合收割机
Redux为您提供了一个实用方法,用于组合几个在状态对象的不同部分上工作的还原器。在本例中,您将创建一个单独处理此对象的notificationBar还原器。
createStore(combineReducers({
notificationBar: function(state=initialNBarState, action) {
switch (action.type) {
case actions.LAYOUT_NOTIFICATIONBAR_OPEN:
return Object.assign({}, state, { open: true });
}
});这使您不必担心顶级属性,这样您就可以避免嵌套对Object.assign的调用。
如果您的状态在逻辑上可以分解为明确定义的部分,那么这可能是解决这个问题的最惯用的方法。
使用不可变数据
可以使用持久数据结构库创建数据结构,而不是修改以返回副本。
莫里
Mori是将Clojure的数据结构和functional编译成JS的结果。
import { hashMap, updateIn } from 'mori';
const initialState = hashMap(
"notificationBar", hashMap(
"open", false
)
);
// ...
return updateIn(state, ['notificationBar', 'open'], true);ImmutableJS
ImmutableJS是一种更必要的方法,可以将哈希数组映射的尝试的语义从Clojure的持久数据结构转移到Javascript。
import { Map } from 'immutable';
const initialState = Map({
notificationBar: Map({
open: true
});
});
// ...
return state.setIn(['notificationBar', 'open'], true);别名Object.assign
您可以创建一个更友好的Object.assign版本来编写上面代码的简洁版本。实际上,它几乎可以和...运算符一样简洁。
function $set(...objects) {
return Object.assign({}, ...objects);
}
return $set(state, {
notificationBar: $set(state.notificationBar, {
open: true,
})
});使用不变的帮手
还有许多库也提供了对常规可变对象进行修改的不可变帮助程序。
更新
React在很长一段时间内都有一套不变的帮手。它们使用与MongoDB查询类似的语法。
import update from 'react-addons-update';
return update(state, {
notificationBar: {
open: { $set: true }
}
});道具不可变
此库允许您使用熟悉的点路径来指定(嵌套)属性的更新。
import dotProp from 'dot-prop-immutable';
return dotProp.set(state, 'notificationBar.open', true);最新情况
这个库是react-addons-update的包装器,它为更新(嵌套)属性提供了更多的功能语法。
不是传递一个新值,而是传递一个接受旧值并返回新值的函数。
import updateIn from 'update-in';
return updateIn(state, ['notificationBar', 'open'], () => true);不可变路径
对于更新属性,此库类似于dot-prop-immutable和update-in之间的交叉。
import path from 'immutable-path';
return path.map(state, 'notificationBar.open', () => true);发布于 2016-12-27 09:50:34
你可以用镜片。
import { set, makeLenses } from '@DrBoolean/lenses'
const L = makeLenses(['notificationBar', 'open']);
const notificationBarOpen = compose(L.notificationBar, L.open)
const setNotificationBarOpenTrue = set(notificationBarOpen, true)
const a = { notificationBar: { open: false } }
const b = setNotificationBarOpenTrue(a)
// `a` is left unchanged and `b` is `{ notificationBar: { open: true } }`您可以将镜头视为组合属性访问/更新。
关于镜片的一些好资源:
如果您可以阅读lisps,我也会建议您看看这个优秀的介绍的镜头从球拍文档。最后,如果您想深入阅读haskell,您可以查看:镜片.组合数据存取和操作。
https://stackoverflow.com/questions/35592078
复制相似问题