2016-08-29 15 views
3

状態のスライス全体を完全に置き換えた場合でも、元の状態のコピーを作成して置き換えるにはObject.assignまたはスプレッド演算子を使用する必要がありますかそれは新しい国家と一緒になっているのですか、私は単に私の減速家に新しい国家を返すことができますか?コピーを作成せずにreact redux reducerの新しい状態を置換する

const fetching = (state = { isFetching: false }, action) => { 
    switch (action.type) { 
    case 'REQUESTING': 
     return Object.assign({}, state, { isFetching: true }) 
    case 'RECEIVE_POKEMON_TYPE_INFO': 
     return Object.assign({}, state, { isFetching: false }) 
    default: 
     return state 
    } 
} 

const fetching = (state = { isFetching: false }, action) => { 
    switch (action.type) { 
    case 'REQUESTING': 
     return { isFetching: true } 
    case 'RECEIVE_POKEMON_TYPE_INFO': 
     return { isFetching: false } 
    default: 
     return state 
    } 
} 
+0

'Object.assign({}、{isFetching:true})'を返すと 'return Object.assign({}、state、{isFetching:true})'を置き換えることができ、 {isFetching:true} '。そうしないと、残りの状態が失われるため、できません。 – Pandaiolo

+0

私はそこに同様の質問が答えていると思う[ここ](http://stackoverflow.com/q/35002802/1973908) –

+0

私はそこに同様の質問が答えていると思う[ここ](http://stackoverflow.com/ q/35002802/1973908)。 –

答えて

0

あなたはObject.assignを使用して

以下

のように、Object.assignまたはspread operatorを使用することができ、次のいずれか

const fetching = (state = { isFetching: false }, action) => { 
    switch (action.type) { 
    case 'REQUESTING': 
     return Object.assign({}, state, { isFetching: true }) 
    case 'RECEIVE_POKEMON_TYPE_INFO': 
     return Object.assign({}, state, { isFetching: false }) 
    default: 
     return state 
    } 
} 

U演算子を広める歌う:Object.assign()を使用して

const fetching = (state = { isFetching: false }, action) => { 
    switch (action.type) { 
    case 'REQUESTING': 
     return { ...state, isFetching: true } 
    case 'RECEIVE_POKEMON_TYPE_INFO': 
     return { ...state, isFetching: false } 
    default: 
     return state 
    } 
} 

はすぐに、より簡潔な方法であるオブジェクトから別のオブジェクトの列挙プロパティをコピーするには、そのかなりverbose syntax .theのspread (...)オペレータを与え読み取るために、単純な減速が困難になることができます。

2

ここではいくつかのことが起こっています。基本的に、あなたの状態だけがブール変数で構成されている場合、列挙によって新しいオブジェクトを作成することはOKです。しかし、あなたの状態が他のもので構成されている場合は、object.assignを実行すると効果があります。

あなたの状態が複雑な場合(つまり、それが他のオブジェクトで構成されている場合)、object.assignはフィールドを正しくコピーしません。 。たとえば、状態が "currentlySelectedPokemon"フィールドで構成されている場合、その値はポケモンオブジェクトであり、Object.assignはポケモンオブジェクトへの参照をコピーします。オブジェクト自体をコピーすることはありません。これをより簡単に表示するには、以下のコードを見てください。obj2に "value2"が表示されます。

var obj1 = { 
 
    field: { 
 
    subfield: "value" 
 
    } 
 
}; 
 

 
var obj2 = Object.assign({}, obj1); 
 

 
obj1.field.subfield = "value2"; 
 

 
console.log(JSON.stringify(obj2, null, 2));

これを回避するには、2つの方法があります。最初は、すべての状態で不変ライブラリを使用することです。しかし、複雑なオブジェクトを不変に変換して戻すオーバーヘッドを発見したので、複雑さが増し、不必要なバグが導入されました。だから今、私はこれを行う:

const fetching = (state = { isFetching: false }, action) => { 
 
    switch (action.type) { 
 
    case 'REQUESTING': 
 
     const newState = JSON.parse(JSON.stringify(state)); 
 
     newState.isFetching = true; 
 
     return newState; 
 
    case 'RECEIVE_POKEMON_TYPE_INFO': 
 
     const newState = JSON.parse(JSON.stringify(state)); 
 
     newState.isFetching = false; 
 
     return newState; 
 
    default: 
 
     return state 
 
    } 
 
}

それはJSON.parse(JSON.stringify(オブジェクト))バニラJavaオブジェクトのコピーを作成するための高速で信頼性の高い方法であることが判明しました。それはすべての機能(私が一般的に望むもの)を取り除きます。ブラウザは通常ネイティブコードでこれらの関数を実装するため、高速です。

+0

なぜ私は他のデータを持っていればいいのですか?私が1つのデータを置き換える限り、古い状態を置き換える新しいオブジェクトを返すことはできませんか? – mangocaptain

+1

いくつかの問題があります。私を最も痛感させるのは、データをストアに入れた後にデータを変更する他のコードがあれば、ストア内のデータも変更できるということです。 Reduxストアは変更されていますが、Reduxは変更通知を送信していないため、追跡が困難な非常に奇妙な問題が発生します。 –

+0

古い状態のコピーを作成し、それを新しい状態に置き換えるのではなく、コピーを作成せずに新しい状態に置き換えることによって、reduxストアの変更によってreduxが通知を送信することが保証されますか? – mangocaptain

関連する問題