尽管可以使用扩展运算符,但还有许多其他方法可以实现相同的结果,甚至不需要未来的 JS 编译器来实现非标准化功能。以下是一些其他选项,没有特定的顺序。
返回文字
如果您确定您的状态不会增长,那么您可以简单地将整个新状态作为文字返回。
return {
notificationBar: {
open: true
}
}
但是,这通常并不合适,因为您的状态不太可能如此简单。
组合减速器
Redux 为您提供了一种实用方法,用于组合在状态对象的不同部分工作的多个 reducer。在这种情况下,您将创建一个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 的数据结构和函数式 API 编译成 JS 的结果。
import { hashMap, updateIn } from 'mori';
const initialState = hashMap(
"notificationBar", hashMap(
"open", false
)
);
// ...
return updateIn(state, ['notificationBar', 'open'], true);
不可变JS
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插件更新
很长一段时间以来,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);