web-dev-qa-db-ja.com

スプレッド演算子とデストラクタ演算子を使用して不変オブジェクトを変更する最短の方法は何ですか

不変の状態オブジェクトを変更するための純粋な関数を探しています。パラメーターとして指定された元の状態はそのままでなければなりません。これは、 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;
}

短くなりそうだ

26
Tarion

状態に対するアクション。状態は不変と見なされます。

プロパティの値の追加または更新

// 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);
}
62
Tarion

もう少しサポートされているES6ソリューションは Object.assign

const updateState = (state, item) => Object.assign({}, state, { [item.id]: item });
7
Ori Drori

マップ関数で

オブジェクトの配列を指定して、マップ関数内でこのプロセスを実行するには(属性を削除し、各オブジェクトに新しい属性を追加します)-

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 を参照してください。

2
Aidan Ewen

試してください:

const { id, ...noId } = state;

そしてテスト:

console.log(noId);
0
ali

定型コードを書く代わりに(上記のように:(({[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()
   }))
}
0