我正在寻找一个纯函数,来修改我的不可变状态对象。作为参数给出的原始状态必须保持不变。这在使用像Redux这样的框架时特别有用,并且可以更轻松地在javascript中使用immutable对象。特别是因为使用Babel处理对象扩展操作符已经成为可能。
我没有找到比首先复制对象更好的东西,而是分配/删除我想要的属性:
function updateState(state, item) {
newState = {...state};
newState[item.id] = item;
return newState;
}
function deleteProperty(state, id) {
var newState = {...state};
delete newState[id];
return newState;
}
我觉得它可能会更短
对状态的操作,其中state被认为是不可变的。
添加或更新属性的值:
// ES6:
function updateState(state, item) {
return Object.assign({}, state, {[item.id]: item});
}
// With Object Spread:
function updateState(state, item) {
return {
...state,
[item.id]: item
};
}
删除属性
// ES6:
function deleteProperty(state, id) {
var newState = Object.assign({}, state);
delete newState[id];
return newState;
}
// With Object Spread:
function deleteProperty(state, id) {
let {[id]: deleted, ...newState} = state;
return newState;
}
// Or even shorter as helper function:
function deleteProperty({[id]: deleted, ...newState}, id) {
return newState;
}
// Or inline:
function deleteProperty(state, id) {
return (({[id]: deleted, ...newState}) => newState)(state);
}
有更多支持的ES6解决方案是Object.assign
:
const updateState = (state, item) => Object.assign({}, state, { [item.id]: item });
在地图功能中
在给定一个对象数组的情况下,在map函数中执行此过程(删除属性并在每个对象上添加新属性) -
const myArrayOfObjects = [
{id: 1, keyToDelete: 'nonsense'},
{id: 2, keyToDelete: 'rubbish'}
];
删除属性keyToDelete
,并添加值为newKey
的新密钥"someVar"
。
myArrayOfObjects.map(({ keyToDelete, ...item}) => { ...item, newKey:'someVar'});
将阵列更新为
[
{id: 1, newKey:'someVar'},
{id: 2, newKey:'someVar'}
]
有关删除方法的更多信息,请参阅this great post。
而不是编写难以阅读的样板代码(如上所述:(({[id]: deleted, ...state}) => state)(state)
),您可以使用一些库来做同样的事情:
例如:
import {remove} from 'immutable-modify'
function updateState(state, item) {
return remove(state, item.id)
}
它还支持任何嵌套更新:
import {set} from 'immutable-modify'
function updateState(state, item) {
return set(state, 'user.products', (products) => ({
...products,
items: products.items.concat(item),
lastUpdate: Date.now()
}))
}
尝试:
const { id, ...noId } = state;
并测试:
console.log(noId);
从数组中删除项目,只需使用过滤器;)
CASE 'REMOVE_ITEM_SUCCESS':
let items = state.items.filter(element => element._id !== action.id);
return {
...state,
items
}