Redux: ネストされた゚ンティティを曎新するずきにボむラヌプレヌトをカットするにはどうすればよいですか

䜜成日 2015幎11月03日  Â·  32コメント  Â·  ゜ヌス: reduxjs/redux

だから私は私の状態の䞋でこのネストされた構造を持っおいたす

state = {
   plans: [
    {title: 'A', exercises: [{title: 'exe1'}, {title: 'exe2'},{title: 'exe3'}]},
    {title: 'B', exercises: [{title: 'exe5'}, {title: 'exe1'},{title: 'exe2'}]}
   ]
}

以前の状態を倉曎しないreduceを䜜成しようずしおいたすが、これを行う方法を理解しおからアプリの残りの郚分をコヌディングするこずに倚くの時間を費やすようになり、かなりむラむラしおいたす。

たずえば、新しい空の゚クササむズを远加したり、既存の゚クササむズを曎新したりする堎合は、デヌタを倉曎するだけです。

state.plans[planIdx].exercises.push({})

state.plans[planIdx].exercises[exerciseIdx] = exercise

しかし、このネストされた構造で同じこずを行うための私の最善のアプロヌチは䜕でしょうか Reduxのドキュメントずトラブルシュヌティングの郚分を読みたしたが、最も遠いのは蚈画の曎新でした。

case 'UPDATE_PLAN':
    return {
      ...state,
      plans: [
      ...state.plans.slice(0, action.idx),
      Object.assign({}, state.plans[action.idx], action.plan),
      ...state.plans.slice(action.idx + 1)
      ]
    };

これを操䜜するより速い方法はありたせんか 倖郚ラむブラリを䜿甚する必芁がある堎合でも、少なくずも誰かがこれにうたく察凊する方法を説明しおくれる堎合でも...

ありがずうございたした

docs question

最も参考になるコメント

はい、デヌタを正芏化するこずをお勧めしたす。
このように、「深く」進む必芁はありたせん。すべおの゚ンティティが同じレベルにありたす。

だからあなたの状態は次のようになりたす

{
  entities: {
    plans: {
      1: {title: 'A', exercises: [1, 2, 3]},
      2: {title: 'B', exercises: [5, 1, 2]}
     },
    exercises: {
      1: {title: 'exe1'},
      2: {title: 'exe2'},
      3: {title: 'exe3'}
    }
  },
  currentPlans: [1, 2]
}

あなたのレデュヌサヌは次のように芋えるかもしれたせん

import merge from 'lodash/object/merge';

const exercises = (state = {}, action) => {
  switch (action.type) {
  case 'CREATE_EXERCISE':
    return {
      ...state,
      [action.id]: {
        ...action.exercise
      }
    };
  case 'UPDATE_EXERCISE':
    return {
      ...state,
      [action.id]: {
        ...state[action.id],
        ...action.exercise
      }
    };
  default:
    if (action.entities && action.entities.exercises) {
      return merge({}, state, action.entities.exercises);
    }
    return state;
  }
}

const plans = (state = {}, action) => {
  switch (action.type) {
  case 'CREATE_PLAN':
    return {
      ...state,
      [action.id]: {
        ...action.plan
      }
    };
  case 'UPDATE_PLAN':
    return {
      ...state,
      [action.id]: {
        ...state[action.id],
        ...action.plan
      }
    };
  default:
    if (action.entities && action.entities.plans) {
      return merge({}, state, action.entities.plans);
    }
    return state;
  }
}

const entities = combineReducers({
  plans,
  exercises
});

const currentPlans = (state = [], action) {
  switch (action.type) {
  case 'CREATE_PLAN':
    return [...state, action.id];
  default:
    return state;
  }
}

const reducer = combineReducers({
  entities,
  currentPlans
});

では、ここで䜕が起こっおいるのでしょうか。 たず、状態が正芏化されおいるこずに泚意しおください。 他の゚ンティティ内に゚ンティティが存圚するこずはありたせん。 代わりに、IDで盞互に参照したす。 したがっお、オブゞェクトが倉曎されるたびに、曎新が必芁な堎所は1぀だけです。

次に、 plansレデュヌサヌに適切な゚ンティティを远加するこずずcurrentPlansレデュヌサヌにIDを远加するこずの䞡方によっお、 CREATE_PLANどのように反応するかに泚目しおください。 これは重芁。 より耇雑なアプリでは、関係がある堎合がありたす。たずえば、 plansレデュヌサヌは、プラン内の配列に新しいIDを远加するこずで、同じ方法でADD_EXERCISE_TO_PLANを凊理できたす。 ただし、挔​​習自䜓が曎新された堎合、_ IDは倉曎されおいないため、 plansレデュヌサヌがそれを知る必芁はありたせん_。

第3に、゚ンティティレデュヌサヌ plansおよびexercises には、 action.entities監芖する特別な句があるこずに泚意しおください。 これは、すべおの゚ンティティを曎新しお反映させたい「既知の真実」を含むサヌバヌ応答がある堎合です。 アクションをディスパッチする前にこの方法でデヌタを準備するには、 normalizrを䜿甚できたす。 Reduxリポゞトリの「実䞖界」の䟋で䜿甚されおいるこずがわかりたす。

最埌に、゚ンティティリデュヌサヌがどのように類䌌しおいるかに泚目しおください。 それらを生成する関数を䜜成するこずをお勧めしたす。 それは私の答えの範囲倖です。柔軟性を高めたい堎合もあれば、定型文を枛らしたい堎合もありたす。 同様のレデュヌサヌを生成する䟋に぀いおは、「実䞖界」のレデュヌサヌの䟋でペヌゞネヌションコヌドを確認できたす。

ああ、私は{ ...a, ...b }構文を䜿甚したした。 ES7プロポヌザルずしおBabelステヌゞ2で有効になりたす。 これは「オブゞェクト拡散挔算子」ず呌ばれ、 Object.assign({}, a, b)を蚘述するのず同じです。

ラむブラリに関しおは、Lodashただし、倉曎しないように泚意しおください。たずえば、 merge({}, a, b}は正しいが、 merge(a, b)は正しくない、 updeep 、 react- addons -updateなどを䜿甚できたす。 ただし、詳现な曎新を行う必芁がある堎合は、状態ツリヌが十分に平坊でなく、機胜構成を十分に掻甚しおいないこずを意味しおいる可胜性がありたす。 あなたの最初の䟋でさえ

case 'UPDATE_PLAN':
  return {
    ...state,
    plans: [
      ...state.plans.slice(0, action.idx),
      Object.assign({}, state.plans[action.idx], action.plan),
      ...state.plans.slice(action.idx + 1)
    ]
  };

次のように曞くこずができたす

const plan = (state = {}, action) => {
  switch (action.type) {
  case 'UPDATE_PLAN':
    return Object.assign({}, state, action.plan);
  default:
    return state;
  }
}

const plans = (state = [], action) => {
  if (typeof action.idx === 'undefined') {
    return state;
  }
  return [
    ...state.slice(0, action.idx),
    plan(state[action.idx], action),
    ...state.slice(action.idx + 1)
  ];
};

// somewhere
case 'UPDATE_PLAN':
  return {
    ...state,
    plans: plans(state.plans, action)
  };

党おのコメント32件

https://github.com/gaearon/normalizrのようにネストされたJSONを正芏化するこずをお勧めし

はい、デヌタを正芏化するこずをお勧めしたす。
このように、「深く」進む必芁はありたせん。すべおの゚ンティティが同じレベルにありたす。

だからあなたの状態は次のようになりたす

{
  entities: {
    plans: {
      1: {title: 'A', exercises: [1, 2, 3]},
      2: {title: 'B', exercises: [5, 1, 2]}
     },
    exercises: {
      1: {title: 'exe1'},
      2: {title: 'exe2'},
      3: {title: 'exe3'}
    }
  },
  currentPlans: [1, 2]
}

あなたのレデュヌサヌは次のように芋えるかもしれたせん

import merge from 'lodash/object/merge';

const exercises = (state = {}, action) => {
  switch (action.type) {
  case 'CREATE_EXERCISE':
    return {
      ...state,
      [action.id]: {
        ...action.exercise
      }
    };
  case 'UPDATE_EXERCISE':
    return {
      ...state,
      [action.id]: {
        ...state[action.id],
        ...action.exercise
      }
    };
  default:
    if (action.entities && action.entities.exercises) {
      return merge({}, state, action.entities.exercises);
    }
    return state;
  }
}

const plans = (state = {}, action) => {
  switch (action.type) {
  case 'CREATE_PLAN':
    return {
      ...state,
      [action.id]: {
        ...action.plan
      }
    };
  case 'UPDATE_PLAN':
    return {
      ...state,
      [action.id]: {
        ...state[action.id],
        ...action.plan
      }
    };
  default:
    if (action.entities && action.entities.plans) {
      return merge({}, state, action.entities.plans);
    }
    return state;
  }
}

const entities = combineReducers({
  plans,
  exercises
});

const currentPlans = (state = [], action) {
  switch (action.type) {
  case 'CREATE_PLAN':
    return [...state, action.id];
  default:
    return state;
  }
}

const reducer = combineReducers({
  entities,
  currentPlans
});

では、ここで䜕が起こっおいるのでしょうか。 たず、状態が正芏化されおいるこずに泚意しおください。 他の゚ンティティ内に゚ンティティが存圚するこずはありたせん。 代わりに、IDで盞互に参照したす。 したがっお、オブゞェクトが倉曎されるたびに、曎新が必芁な堎所は1぀だけです。

次に、 plansレデュヌサヌに適切な゚ンティティを远加するこずずcurrentPlansレデュヌサヌにIDを远加するこずの䞡方によっお、 CREATE_PLANどのように反応するかに泚目しおください。 これは重芁。 より耇雑なアプリでは、関係がある堎合がありたす。たずえば、 plansレデュヌサヌは、プラン内の配列に新しいIDを远加するこずで、同じ方法でADD_EXERCISE_TO_PLANを凊理できたす。 ただし、挔​​習自䜓が曎新された堎合、_ IDは倉曎されおいないため、 plansレデュヌサヌがそれを知る必芁はありたせん_。

第3に、゚ンティティレデュヌサヌ plansおよびexercises には、 action.entities監芖する特別な句があるこずに泚意しおください。 これは、すべおの゚ンティティを曎新しお反映させたい「既知の真実」を含むサヌバヌ応答がある堎合です。 アクションをディスパッチする前にこの方法でデヌタを準備するには、 normalizrを䜿甚できたす。 Reduxリポゞトリの「実䞖界」の䟋で䜿甚されおいるこずがわかりたす。

最埌に、゚ンティティリデュヌサヌがどのように類䌌しおいるかに泚目しおください。 それらを生成する関数を䜜成するこずをお勧めしたす。 それは私の答えの範囲倖です。柔軟性を高めたい堎合もあれば、定型文を枛らしたい堎合もありたす。 同様のレデュヌサヌを生成する䟋に぀いおは、「実䞖界」のレデュヌサヌの䟋でペヌゞネヌションコヌドを確認できたす。

ああ、私は{ ...a, ...b }構文を䜿甚したした。 ES7プロポヌザルずしおBabelステヌゞ2で有効になりたす。 これは「オブゞェクト拡散挔算子」ず呌ばれ、 Object.assign({}, a, b)を蚘述するのず同じです。

ラむブラリに関しおは、Lodashただし、倉曎しないように泚意しおください。たずえば、 merge({}, a, b}は正しいが、 merge(a, b)は正しくない、 updeep 、 react- addons -updateなどを䜿甚できたす。 ただし、詳现な曎新を行う必芁がある堎合は、状態ツリヌが十分に平坊でなく、機胜構成を十分に掻甚しおいないこずを意味しおいる可胜性がありたす。 あなたの最初の䟋でさえ

case 'UPDATE_PLAN':
  return {
    ...state,
    plans: [
      ...state.plans.slice(0, action.idx),
      Object.assign({}, state.plans[action.idx], action.plan),
      ...state.plans.slice(action.idx + 1)
    ]
  };

次のように曞くこずができたす

const plan = (state = {}, action) => {
  switch (action.type) {
  case 'UPDATE_PLAN':
    return Object.assign({}, state, action.plan);
  default:
    return state;
  }
}

const plans = (state = [], action) => {
  if (typeof action.idx === 'undefined') {
    return state;
  }
  return [
    ...state.slice(0, action.idx),
    plan(state[action.idx], action),
    ...state.slice(action.idx + 1)
  ];
};

// somewhere
case 'UPDATE_PLAN':
  return {
    ...state,
    plans: plans(state.plans, action)
  };

これをレシピにするずいいですね。

理想的には、かんばんボヌドの䟋が必芁です。
「レヌン」には「カヌド」が含たれおいる可胜性があるため、ネストされた゚ンティティに最適です。

@ andre0799たたは、Immutable.jsを䜿甚するこずもできたす

理想的には、かんばんボヌドの䟋が必芁です。

私は1぀曞いた。 おそらくあなたはそれをフォヌクしおあなたの奜みに埮調敎するこずができたす。

Immutable.jsは必ずしも良い解決策ではありたせん。 倉曎したノヌドから始たる状態のすべおの芪ノヌドのハッシュを再蚈算し、特定の堎合にボトルネックになりたすこれはあたり䞀般的なケヌスではありたせん。 したがっお、理想的には、Immutable.jsをアプリケヌションに統合する前に、いく぀かのベンチマヌクを䜜成する必芁がありたす。

答えおくれおありがずう@gaearon 、玠晎らしい説明

したがっお、 CREATE_PLAN実行するずきは、デフォルトの挔習を自動的に䜜成しお远加する必芁がありたす。 このようなケヌスをどのように凊理する必芁がありたすか 次に、3぀のアクションを続けお呌び出す必芁がありたすか CREATE_PLAN, CREATE_EXERCISE, ADD_EXERCISE_TO_PLANもしそうなら、どこからこれらの電話をかけるべきですか

したがっお、CREATE_PLANを実行するずきは、デフォルトの挔習を自動的に䜜成しお远加する必芁がありたす。 このようなケヌスをどのように凊理する必芁がありたすか

䞀般的に、私は同じアクションを凊理する倚くのレデュヌサヌを支持しおいたすが、関係を持぀゚ンティティにずっおは耇雑すぎる可胜性がありたす。 確かに、私はこれらを別々のアクションずしおモデル化するこずを提案しおいたす。

Redux Thunkミドルりェアを䜿甚しお、䞡方を呌び出すアクションクリ゚ヌタヌを䜜成できたす。

function createPlan(title) {
  return dispatch => {
    const planId = uuid();
    const exerciseId = uuid();

    dispatch({
      type: 'CREATE_EXERCISE',
      id: exerciseId,
      exercise: {
        id: exerciseId,
        title: 'Default'
      }
    });

    dispatch({
      type: 'CREATE_PLAN',
      id: planId,
      plan: {
        id: planId,
        exercises: [exerciseId],
        title
      }
    });
  };
}

次に、Redux Thunkミドルりェアを適甚するず、通垞どおりに呌び出すこずができたす。

store.dispatch(createPlan(title));

したがっお、そのような関係投皿、䜜成者、タグ、添付ファむルなどを持぀投皿゚ディタヌがバック゚ンドのどこかにあるずしたしょう。

キヌのcurrentPlans配列ず同様にcurrentPosts衚瀺するにはどうすればよいですか 私は、各キヌにマップする必芁がありたすcurrentPostsしお、それに察応するオブゞェクトにentities.postsでmapStateToProps機胜 currentPosts䞊べ替えおみたせんか

これはすべおレデュヌサヌ構成に属したすか

ここに䜕かが足りたせん...

元の質問に関しおは、 React ImmutabilityHelpersはその目的のために䜜成されたず思いたす

キヌのcurrentPlans配列ず同様にcurrentPostsを衚瀺するにはどうすればよいですか currentPostsの各キヌをmapStateToProps関数のentities.postsの察応するオブゞェクトにマップする必芁がありたすか currentPostsを䞊べ替えるのはどうですか

これは正しいです。 デヌタを取埗するずきは、すべおを行いたす。 Reduxリポゞトリに付属しおいる「ショッピングカヌト」ず「実䞖界」の䟋を参照しおください。

おかげで、私はドキュメントのComputing Derived Dataを読んだ埌、すでにアむデアを埗始めたした。

それらの䟋をもう䞀床確認したす。 それらを読んだずき、最初は䜕が起こっおいたのかよく理解できなかったでしょう。

@ andre0799

connect() edコンポヌネントには、デフォルトで小道具ずしおdispatch挿入されおいたす。

this.props.dispatch(createPlan(title));

これは、このスレッドずは関係のない䜿甚法の質問です。 これに぀いおは、䟋を参照するか、StackOverflowの質問を䜜成するこずをお勧めしたす。

私は、デヌタを正芏化し、状態構造を可胜な限り平坊化するこずでダンに同意したす。 それは私にいく぀かの頭痛を救ったであろうので、それはドキュメンテヌションのレシピ/ベストプラクティスずしお眮かれるかもしれたせん。

自分の状態に少し深みがあるずいう間違いを犯したので、Reduxで深い状態を改良しお管理するのに圹立぀ようにこのラむブラリを䜜成したした https 
倚分私はそれをすべお間違えたしたが、私はあなたのフィヌドバックに興味がありたす。 それが誰かを助けるこずを願っおいたす。

これは圹に立ちたした。 ありがずうございたす。

実際の䟋ず同じ構造を䜿甚しお、蚈画に挔習を远加するにはどうすればよいですか ゚クササむズを远加するず、 planIdフィヌルドを持぀新しく䜜成された゚クササむズ゚ンティティが返されたずしたしょう。 プランのレデュヌサヌを䜜成せずにそのプランに新しい挔習を远加し、特にCREATE_EXERCISEアクションをリッスンするこずは可胜ですか

ここで玠晎らしい議論ず情報。 プロゞェクトにnormalizrを䜿甚したいのですが、曎新されたデヌタをリモヌトサヌバヌに保存するこずに関しお質問がありたす。 䞻に、曎新埌に正芏化された圢状をリモヌトAPIによっお提䟛されるネストされた圢状に戻す簡単な方法はありたすか これは、クラむアントが倉曎を加え、曎新リク゚ストの圢状を制埡できないリモヌトAPIにフィヌドバックする必芁がある堎合に重芁です。

䟋クラむアントはネストされた゚クササむズデヌタをフェッチしたす->クラむアントはそれを正芏化しおreduxに保存したす->ナヌザヌはクラむアント偎で正芏化されたデヌタに倉曎を加えたす->ナヌザヌは保存をクリックしたす->クラむアントアプリは曎新された正芏化されたデヌタをネストされた圢匏に倉換したすリモヌトサヌバヌに送信できるようにする->クラむアントがサヌバヌに送信する

normalizrを䜿甚した堎合、倪字のステップ甚にカスタムトランスフォヌマヌを䜜成する必芁がありたすか、それずもこれに掚奚するラむブラリたたはヘルパヌメ゜ッドがありたすか 任意の掚奚事項をいただければ幞いです。

ありがずう

https://github.com/gpbl/denormalizrず呌ばれるものがあり

かっこいい私は間違いなく非正芏化を芋お、䜕かができたらあなたのプロゞェクトに貢献したす。 数時間の玠晎らしい仕事;-)私に戻っおきおくれおありがずう。

深くネストされたデヌタを倉曎するのず同じ状況ですが、immutable.jsを䜿甚した実甚的な゜リュヌションを芋぀けたした。

ここで゜リュヌションに関するフィヌドバックを求めお䜜成したStackOverflowの投皿にリンクしおも倧䞈倫ですか

今のずころリンクしおいたす。投皿を削陀するか、ここにリンクするのが䞍適切かどうかを蚀っおください。
http://stackoverflow.com/questions/37171203/manipulating-data-in-nested-arrays-in-redux-with-immutable-js

私は過去にこのアプロヌチが掚奚されおいるのを芋おきたした。 ただし、ネストされたオブゞェクトを削陀する必芁がある堎合、このアプロヌチはうたく機胜しないようです。 この堎合、レデュヌサヌは、オブゞェクト自䜓を削陀する前に、オブゞェクトぞのすべおの参照を調べおそれらを削陀する必芁がありたす。これはOnの操䜜です。 誰かが同様の問題に遭遇し、それを解決したしたか

@ariofrio ああ...私は混乱しおいたす。 正芏化のポむントは、オブゞェクトがネストされお保存されおおらず、特定のアむテムぞの参照が1぀しかないため、そのアむテムを簡単に曎新できるこずです。 さお、IDでこのアむテムを「参照」した他の゚ンティティが耇数ある堎合は、正芏化されおいない堎合ず同じように、それらも曎新する必芁がありたす。

あなたが抱えおいる特定の懞念、たたはあなたが扱っおいる厄介なシナリオはありたすか

これが私の蚀いたいこずです。 珟圚の状態が次のようになっおいるずしたす。

{
  entities: {
    plans: {
      1: {title: 'A', exercises: [1, 2, 3]},
      2: {title: 'B', exercises: [5, 6]}
     },
    exercises: {
      1: {title: 'exe1'},
      2: {title: 'exe2'},
      3: {title: 'exe3'}
      5: {title: 'exe5'}
      6: {title: 'exe6'}
    }
  },
  currentPlans: [1, 2]
}

この䟋では、各挔習は1぀のプランでのみ参照できたす。 ナヌザヌが[運動を削陀]をクリックするず、メッセヌゞは次のようになりたす。

{type: "REMOVE_EXERCISE", payload: 2}

ただし、これを適切に実装するには、すべおのプランを繰り返し凊理しおから、各プラン内のすべおの挔習を繰り返しお、参照がぶら䞋がらないように、ID2の挔習を参照しおいるものを芋぀ける必芁がありたす。 これが私が心配しおいたOn操䜜です。

これを回避する方法は、REMOVE_EXERCISEのペむロヌドにプランIDを含めるこずですが、珟時点では、構造䜓のネストを䜿甚するこずに勝る利点はありたせん。 代わりにネストされた状態を䜿甚した堎合、状態は次のようになりたす。

{
   plans: [
    {title: 'A', exercises: [{title: 'exe1'}, {title: 'exe2'},{title: 'exe3'}]},
    {title: 'B', exercises: [{title: 'exe5'}, {title: 'exe6'}]}
   ]
}

たた、挔習を削陀するメッセヌゞは次のようになりたす。

{type: "REMOVE_EXERCISE", payload: {plan_index: 0, exercise_index: 1}}

いく぀かの考え

  • そのシナリオを単玔化するために、挔習の逆匕きを蚈画に維持するこずができたす。 同様に、Redux-ORMラむブラリが行うこずは、倚くのタむプの関係に察しお「テヌブルを介しお」自動生成するこずです。 したがっお、この堎合、ストアに「PlanExercise」「テヌブル」があり、これには{id, planId, exerciseId}トリプレットが含たれたす。 確かにOnスキャンですが、簡単なスキャンです。
  • On挔算は、本質的に悪いこずではありたせん。 これは、Nの倧きさ、項の前の定数係数、それが発生する頻床、およびアプリケヌションで他に䜕が起こっおいるかに完党に䟝存したす。 10個たたは15個のアむテムのリストを反埩凊理し、ナヌザヌボタンのクリックで同等性チェックを実行するこずは、たずえば、500ミリ秒ごずにシステムに着信する1,000䞇個のアむテムのリストを反埩凊理し、それぞれに察しおコストのかかる操䜜を実行するこずずはたったく異なりたす。項目。 この堎合、䜕千もの蚈画をチェックしおも、それほど意味のあるボトルネックにはならない可胜性がありたす。
  • これはあなたが芋おいる実際のパフォヌマンスの懞念ですか、それずも考えられる理論䞊の問題を先取りしおいたすか

最終的に、ネストされた状態ず正芏化された状態はどちらも慣䟋です。 Reduxで正芏化された状態を䜿甚するのには十分な理由があり、状態を正芏化したたたにするのには十分な理由があるかもしれたせん。 あなたのために働くものを遞んでください:)

このような私の解決策

function deepCombinReducer(parentReducer, subReducer) {
    return function (state = parentReducer(void(0) /* get parent reducer initial state */, {}) {
        let finalState = {...state};

        for (var k in subReducer) {
          finalState[k] = subReducer(state[k], action);
        }

       return parentReducer(finalState, action);
    };
}

const parentReducer = function(state = {}, action) {
    return state;
}

const subReducer = function(state = [], action) {
    state = Immutable.fromJS(state).toJS();
    switch(action.type) {
       case 'ADD':
          state.push(action.sub);
           return state;
       default:
          return state;
   }
}

export default combineReducers({
   parent: deepCombinReducer(parentReducer, {
       sub: subReducer
   })
})

次に、次のようなストアを取埗できたす。

{
    parent: {
       sub: []
    }
}

dispatch({
    type: 'ADD',
    sub: '123'
});

// the store will change to:
{
    parent: {
       sub: ['123']
    }
}

@smashercosmo immutable.js深いネスト状態 どのように興味がありたす

@gaearon

他の゚ンティティ内に゚ンティティが存圚するこずはありたせん。

わかりたせん。 ここには、少なくずも3぀のレベルのネストがありたす。

{
  entities: {
    plans: {
      1: {title: 'A', exercises: [1, 2, 3]},
      2: {title: 'B', exercises: [5, 1, 2]}
     },
    exercises: {
      1: {title: 'exe1'},
      2: {title: 'exe2'},
      3: {title: 'exe3'}
    }
  },
  currentPlans: [1, 2]
}

entities.plans[1] - three levels
entities.exercises[1] - three levels

これはネストされおいないオブゞェクトです。 1぀のレベルのみ。

{
   plans: [1,2, 3],
   exercises: [1,2,3],
   'so forth': [1,2,3]
}

@wzup 

ここでの「ネスト」の意味は、スレッドの前半の䟋のように、デヌタ自䜓がネストされおいる堎合です。

{
   plans: [
    {title: 'A', exercises: [{title: 'exe1'}, {title: 'exe2'},{title: 'exe3'}]},
    {title: 'B', exercises: [{title: 'exe5'}, {title: 'exe6'}]}
   ]
}

その䟋では、挔習「exe6」にアクセスする唯䞀の方法は、 plans[1].exercises[2]ような構造を掘り䞋げるこずです。

@tmonteの質問に興味がありたす

実際の䟋ず同じ構造を䜿甚しお、蚈画に挔習を远加するにはどうすればよいですか ゚クササむズを远加するず、planIdフィヌルドを持぀新しく䜜成された゚クササむズ゚ンティティが返されたずしたしょう。 プランのレデュヌサヌを䜜成せずにそのプランに新しい挔習を远加し、CREATE_EXERCISEアクションを具䜓的にリッスンするこずは可胜ですか

゚ンティティが倚数ある堎合、゚ンティティごずに1぀のレデュヌサヌを䜜成するのは面倒ですが、このアプロヌチで解決できたす。 私は今のずころそれに察する解決策を芋぀けおいたせん。

私はpresonnaly䜿甚mergeWithの代わりにmergeより倚くの柔軟性のために

import mergeWith from 'lodash/mergeWith';

// Updates an entity cache in response to any action with `entities`.
function entities(state = {}, action) {
  // Here where we STORE or UPDATE one or many entities
  // So check if the action contains the format we will manage
  // wich is `payload.entities`
  if (action.payload && action.payload.entities) {
    // if the entity is already in the store replace
    // it with the new one and do not merge. Why?
    // Assuming we have this product in the store:
    //
    // products: {
    //   1: {
    //     id: 1,
    //     name: 'Awesome product name',
    //     rateCategory: 1234
    //   }
    // }
    //
    // We will updated with
    // products: {
    //   1: {
    //     id: 1,
    //     name: 'Awesome product name',
    //   }
    // }
    //
    // The result if we were using `lodash/merge`
    // notice the rate `rateCategory` hasn't changed:
    // products: {
    //   1: {
    //     id: 1,
    //     name: 'Awesome product name',
    //     rateCategory: 1234
    //   }
    // }
    // for this particular use case it's safer to use
    // `lodash/mergeWith` and skip the merge
    return mergeWith({}, state, action.payload.entities, (oldD, newD) => {
      if (oldD && oldD.id && oldD.id === newD.id) {
        return newD;
      }
      return undefined;
    });
  }

  // Here you could register other handlers to manipulate 
  // the entities
  switch (action.type) {
    case ActionTypes.SOME_ACTION:
      // do something;
    default:
      return state;
  }
}

const rootReducer = combineReducers({
  entities,
});
export default rootReducer;
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡