不変の状態オブジェクトを変更するための純粋な関数を探しています。パラメーターとして指定された元の状態はそのままでなければなりません。これは、 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;
}
短くなりそうだ
状態に対するアクション。状態は不変と見なされます。
プロパティの値の追加または更新:
// 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 });
マップ関数で
オブジェクトの配列を指定して、マップ関数内でこのプロセスを実行するには(属性を削除し、各オブジェクトに新しい属性を追加します)-
const myArrayOfObjects = [
{id: 1, keyToDelete: 'nonsense'},
{id: 2, keyToDelete: 'rubbish'}
];
属性keyToDelete
を削除し、値"someVar"
を持つ新しいキーnewKey
を追加します。
myArrayOfObjects.map(({ keyToDelete, ...item}) => { ...item, newKey:'someVar'});
配列を更新する
[
{id: 1, newKey:'someVar'},
{id: 2, newKey:'someVar'}
]
削除方法の詳細については、 this great post を参照してください。
試してください:
const { id, ...noId } = state;
そしてテスト:
console.log(noId);
定型コードを書く代わりに(上記のように:(({[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()
}))
}