2016-12-21 1 views
1

州のどの部分がReduxレデューサーに深くクローンされていると思われますか?私は長い間、このように私のレデューサーを書いている

const init = { 
    a: 'b' 
} 

const reducerName = function (state = init, action) { 
    let newState = _.cloneDeep(state) // using lodash 
    case 'ACTION_NAME': 
    newState.a = 'c' 
    return newState 
    default: 
    return state 
} 

ある日、私はすべてのすべての減速に新しいオブジェクトを作成していますので、私は、これはおそらくそれを行うのは非常に愚かな方法であることを、実現しました状態がまったく変更されない場合でも、アクションがトリガされる時間。

私の同僚は私にダン・アブラモフのつぶやきを渡しました。そこでは、州を深くクローンする必要はないと言います。そして、これは私に、実際に深いクローンを行う時期と方法を考えさせました。

のは、私が減速状態のこの種を持っているとしましょう:

const init = { 
    very: { 
    deeply: { 
     nested: 'string' 
    } 
    } 
    notSoDeeplyNested: 'string' 
} 

だから、これは、次のいずれかが正しい方法/最も近い状態を管理行うための正しい方法を次のようになります。

1 )

const reducerName = function (state = init, action) { 
    case 'ACTION_NAME': 
    let newState = Object.assign({}, state) // Make a shallow copy 
    newState.very.deeply = action.deeply 
    return newState 
    default: 
    return state 
} 

2)

const reducerName = function (state = init, action) { 
    case 'ACTION_NAME': 
    let newVery = _.cloneDeep(state.very) 
    let newState = Object.assign({}, state, very) 
    newState.very.deeply = action.deeply 
    return newState 
    default: 
    return state 
} 

3)

const reducerName = function (state = init, action) { 
    case 'ACTION_NAME': 
    let newDeeply = _.cloneDeep(state.very.deeply) 
    let newState = Object.assign({}, state, { very: { deeply: newDeeply }) // Cloning only the nested part, which actually changes? 
    newState.very.deeply = action.deeply 
    return newState 
    default: 
    return state 
} 

最後のものも私のために適切ないないようですが、私はつらい時、このまわりで私の頭をラップしています。

少なくとも、浅いコピーは毎回行う必要があると私は理解していますが、何かを深くクローンすると思いますか?そして、それが最初のレベルのオブジェクトかネストされた部分だけを意味しますか?

+0

「正しい方法」とはどういう意味ですか?コードの可読性など、パフォーマンスに関心がありますか? –

答えて

3

質問に答えるには:いいえ、あなたは深くクローンしません。代わりに、変更が必要な部品を選択的にシャープコピーします。非構造化部分への既存の参照を保持しながら、変更を伴うパスのみをターゲットにするために、非構造化を使用できます。

次の例では、initをオブジェクトにシャローコピーしますが、veryを新しいオブジェクトで置き換えます。同じことがveryオブジェクトについても起こります。 init.veryのすべてを浅くコピーしますが、deeplyを新しい値で置き換えます。これは、ES5でこれに変換

case 'ACTION_NAME': 
    return { 
    ...init, 
    very: { 
     ...init.very, 
     deeply: action.deeply 
    } 
    }; 

:最後に

case 'ACTION_NAME': 
    return Object.assign({}, init, 
    {very: Object.assign({}, init.very, 
     {deeply: action.deeply})}); 

、あなたは、部分的に既存の値と参照で構成された新しい状態オブジェクトを持ち、そしてそれに一部が変更された値の、類似しました永続的なデータ構造の私たちは、変更されたデータにつながるオブジェクトを変更しましたが、深いクローンと呼ぶことができるようにすべてを変更しませんでした。

深い構造の場合は冗長になりますが、深く入れ子構造の場合はRedux advocates shallow objectsではなく冗長になります。

関連する問題