ffx*_*sam 29 javascript reactjs redux
有时减速器会变得混乱:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
是否有更简洁的方法来做到这一点?
Dan*_*nce 46
虽然可以使用扩展运算符,但是有很多其他方法可以实现相同的结果,甚至不需要将来的JS编译器用于非标准化功能.以下是一些其他选项,没有特别的顺序.
如果您确定您的状态不会增长,那么您可以简单地将整个新状态作为文字返回.
return {
notificationBar: {
open: true
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这通常不合适,因为你的州不太可能这么简单.
Redux为您提供了一种实用方法,用于组合在状态对象的不同部分上工作的多个Reducer.在这种情况下,您将创建一个notificationBar仅处理此对象的reducer.
createStore(combineReducers({
notificationBar: function(state=initialNBarState, action) {
switch (action.type) {
case actions.LAYOUT_NOTIFICATIONBAR_OPEN:
return Object.assign({}, state, { open: true });
}
});
Run Code Online (Sandbox Code Playgroud)
这可以防止您不必担心顶级属性,这样就可以避免嵌套调用Object.assign.
如果您的状态可以在逻辑上划分为明确定义的部分,那么这可能是解决此问题的最惯用的方法.
您可以使用持久性数据结构库来创建数据结构,而不是可以修改以返回副本.
Mori是将Clojure的数据结构和功能API编译成JS的结果.
import { hashMap, updateIn } from 'mori';
const initialState = hashMap(
"notificationBar", hashMap(
"open", false
)
);
// ...
return updateIn(state, ['notificationBar', 'open'], true);
Run Code Online (Sandbox Code Playgroud)
ImmutableJS是将Hash Array Mapped Tries的语义从Clojure的持久数据结构带入Javascript的更为迫切的方法.
import { Map } from 'immutable';
const initialState = Map({
notificationBar: Map({
open: true
});
});
// ...
return state.setIn(['notificationBar', 'open'], true);
Run Code Online (Sandbox Code Playgroud)
Object.assign您可以创建更友好的版本Object.assign来编写上面代码的高级版本.事实上,它几乎与...运营商一样简洁.
function $set(...objects) {
return Object.assign({}, ...objects);
}
return $set(state, {
notificationBar: $set(state.notificationBar, {
open: true,
})
});
Run Code Online (Sandbox Code Playgroud)
有许多库也提供不变性助手,用于修改常规可变对象.
React长期拥有一套内置的不变性助手.它们使用与MongoDB查询类似的语法.
import update from 'react-addons-update';
return update(state, {
notificationBar: {
open: { $set: true }
}
});
Run Code Online (Sandbox Code Playgroud)
此库允许您使用熟悉的点路径指定(嵌套)属性的更新.
import dotProp from 'dot-prop-immutable';
return dotProp.set(state, 'notificationBar.open', true);
Run Code Online (Sandbox Code Playgroud)
该库是一个包装器react-addons-update,为更新(嵌套)属性提供了更多功能的语法.
您传递的函数不是传递新值,而是传递旧值并返回一个新值.
import updateIn from 'update-in';
return updateIn(state, ['notificationBar', 'open'], () => true);
Run Code Online (Sandbox Code Playgroud)
对于更新属性,此库就像是dot-prop-immutable和之间的交叉update-in.
import path from 'immutable-path';
return path.map(state, 'notificationBar.open', () => true);
Run Code Online (Sandbox Code Playgroud)
zer*_*kms 45
UPD:它现在是ES2018的一部分
它可能会通过非标准化但属性扩展语法略微改进:
return {
...state,
notificationBar: {
...state.notificationBar,
open: true,
},
};
Run Code Online (Sandbox Code Playgroud)
你可以使用镜头.
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 } }`
Run Code Online (Sandbox Code Playgroud)
您可以将镜头视为组合属性访问/更新.
关于镜片的一些好资源:
如果您对阅读lisps感到满意,我还建议您从球拍文档中了解镜片的这一优秀介绍.最后,如果你想更深入,并且可以阅读haskell,你可以观看:镜头 - 组合数据访问和操作.
| 归档时间: |
|
| 查看次数: |
20424 次 |
| 最近记录: |