web-dev-qa-db-ja.com

レデューサーでネストされたオブジェクトの値を更新する方法は?

私はそのように自分の状態を構築しました

const list = {
  categories: {
   Professional: {
    active: false,
    names: [
      {
        id: 1,
        name: "Golf",
        active: false
      },
      {
        id: 2,
        name: "Ultimate Frisbee",
        active: false
      }
  ] 
}}

私のアクションではIDオプションを追加しましたので、ユーザーがオプションをクリックしてアクティブステータスを変更したいと思います

私はImmutable JSを使用していますが、それと結婚していません。オブジェクトのidをターゲットにし、reducerでそのアクティブステータスを更新する方法を疑問に思っていますか?自分の状態を改善する方法についてのフィードバックも受け付けています。

25
albert

これは非常に一般的なことであり、実際、非常に困難です。私の知る限り、プレーンなJSには、本当によく採用されたソリューションはありません。最初は、Object.assignアプローチが使用されました。

return Object.assign({}, state, {
  categories: Object.assign({}, state.categories, {
    Professional: Object.assign({}, state.Professional, {
      active: true
    })
  })
});

これは非常に単純で面倒です、私は認めますが、このアプローチで構築した大きなアプリケーションはほとんどなく、文字数を除いて悪くないことを言わなければなりません。現在、最も一般的なアプローチは Object spread を使用することです。

return {
  ...state,
  categories: {
    ...state.categories,
    Professional: {
      ...state.categories.Professional,
      active: true
    }
  }
}

2番目のアプローチはよりクリーンであるため、プレーンJSを使用する場合は、適切な選択と思われます。 Immutable.jsでは、次のことを行うだけで簡単になります。

return state.updateIn(['categories', 'Professional'], x => x.set('active', true));

ただし、独自の欠点と注意事項があるため、コミットする前に真剣に考えることをお勧めします。

そして、状態の改善に関する最後の質問–通常、そのような深いネストを持たない方が良いです(懸念を分離し、フィールドは互いに依存しないことがよくあります-activeステータスは別のオブジェクトに分離できます) 、しかし、ドメインの知識がないために言うのは難しいです。また、それは normalize あなたのデータの正常なものと見なされます。

43
Bloomca

Reducturing Reducers のReduxのドキュメントセクションでこれについて説明します。特に、 Immutable Update Patterns のセクションを参照してください。与えられた例は、プレーンなJSオブジェクトと配列用ですが、同じアプローチが適用されます-map()はリスト上で、あなたdo n't更新し、更新する新しいバージョンを返しますdo

ドキュメントごとに、データを正規化された構造に保存すると、IDで直接検索できるため、特定のアイテムを更新する方が簡単であることに注意してください。 「レデューサーの構造化」セクションでは、正規化についても説明します。

6
markerikson