2017-05-06 17 views
0

スライス全体を更新することなく、自分の状態のスライスを更新する必要があります。サブスライスのみ。私は他の人がこれを達成するために減速機を組み合わせるのを見てきましたが、私のプロジェクトでこれをどうやって行うのかまだ分かりませんでした。 Redux.js.orgはこれを別の方法として示しています。スプレッドオペレータなしでRedux状態のサブスライスを変更する方法

function updateVeryNestedField(state, action) { 
    return { 
     ....state, 
     first : { 
      ...state.first, 
      second : { 
       ...state.first.second, 
       [action.someId] : { 
        ...state.first.second[action.someId], 
        fourth : action.someValue 
       } 
      } 
     } 
    } 
} 

残念ながら、私のプロジェクトはJavaScriptで書かれています。どのように私は普及したオペレータなしでバニラのjavascriptでこれを複製できますか? Object.assignを使用していくつかのバリエーションを試しましたが、うまく動作しませんでした。

答えて

1

あなたが述べたように、あなたは、スプレッドの代わりにObject.assignを使用することができます。

{...state, x: 1} 

Object.assign({}, state, {x: 1}) 

とあなたに同じ結果を与える必要がありObject.assignの最初のパラメータとして空のオブジェクトに注意してください。これは、stateの値を新しい空のオブジェクトにコピーし、{first: 1}の値を新しいオブジェクトにコピーすることです。例えば

var a = { x: 1, y: 2} 
var b = {...a, y: 3 } 
console.log(a); // { x: 1, y: 2 } 
console.log(b); // { x: 1, y: 3 } 

ac両方が不変であることである

var c = { x: 1, y: 2 } 
var d = Object.assign({}, a, { y: 3 }); 
console.log(c); // { x: 1, y: 2 } 
console.log(d); // { x: 1, y: 3 } 

重要な部分に相当します。 bdの新しい値はyです。ネストされたオブジェクトの場合

、あなたは、このプロセスを繰り返します

function updateVeryNestedField(state, action) { 
    return Object.assign({}, state, { 
     first : Object.assign({}, state.first, { 
      second : Object.assign({}, state.first.second, { 
       [action.someId] : Object.assign({}, 
        state.first.second[action.someId], 
        { fourth : action.someValue } 
       ) 
      }) 
     }) 
    }); 
} 

var oldState = { first: { second: { 'anId': { fourth: 3 } } } }; 
var newState = updateVeryNestedField(oldState, { someId: 'anId', someValue: 5 }); 
console.log(oldState.first.second.anId.fourth); // 3 
console.log(newState.first.second.anId.fourth); // 5 

しかし、フルES2015をサポートするために、あなたはまた、use computed keysすることができません。だから代わりにreturn文の前にオブジェクトのいくつかを構築しておきます。例:

function updateVeryNestedField(state, action) { 
    // Create a temporary object to avoid use of computed keys 
    var updatedSecond = Object.assign({}, state.first.second); 
    updatedSecond[action.someId] = Object.assign({}, state.first.second[action.someId], { 
     fourth: action.someValue 
    }); 
    return Object.assign({}, state, { 
     first : Object.assign({}, state.first, { second : updatedSecond }) 
    }); 
} 

var oldState = { first: { second: { 'anId': { fourth: 3 } } } }; 
var newState = updateVeryNestedField(oldState, { someId: 'anId', someValue: 5 }); 
console.log(oldState.first.second.anId.fourth); // 3 
console.log(newState.first.second.anId.fourth); // 5 
+0

ありがとうございます。 – skwny

+0

これはes5で許されますか? '[action.someId]:...'? uglifier.jsで縮小するとエラーが発生しますが、他の人もこの問題を経験しています。しかし、バンドルしているが、小型化していないときは通り過ぎる。 – skwny

+0

@skwy残念ながら計算されたキーはES2015の一部です。一時オブジェクトを導入して計算されたキーを使用しないようにする方法を示すために私の例を更新しました。この新しい例では、インデックスを使用して一時オブジェクトにプロパティを追加しています。 – grovesNL

関連する問題