web-dev-qa-db-fra.com

Comment mettre à jour une valeur d'un objet imbriqué dans un réducteur?

J'ai construit mon état comme ça

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

Dans mon action, j'ai ajouté une option d'identification, donc je voudrais changer le statut actif lorsque l'utilisateur clique sur l'option pour le faire

J'utilise Immutable JS bien que je ne sois pas marié avec. Je me demande comment cibler l'identifiant de l'objet et mettre à jour son état actif dans un réducteur? Je suis également ouvert aux commentaires sur la meilleure façon d'améliorer mon état

25
albert

C'est une chose très courante et, en fait, assez intimidante. Pour autant que je sache, il n'y a pas de solution vraiment bonne et bien adoptée dans JS ordinaire. Initialement, Object.assign l'approche a été utilisée:

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

C'est trop simple et trop lourd, je l'admets, mais je dois dire que nous avons construit quelques grandes applications avec cette approche, et à part le nombre de caractères, ce n'est pas mauvais. De nos jours, l'approche la plus populaire utilise Object spread :

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

La deuxième approche est beaucoup plus propre, donc si vous utilisez du JS ordinaire, cela semble être un bon choix. Dans Immutable.js, je dois admettre que c'est plus facile, vous faites juste la prochaine

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

Mais il a ses propres inconvénients et mises en garde, il est donc préférable d'y penser sérieusement avant de s'y engager.

Et votre dernière question concernant l'amélioration de l'état - il est généralement préférable de ne pas avoir une imbrication aussi profonde (séparez vos préoccupations, très souvent les champs ne dépendent pas les uns des autres - comme le statut active peut être séparé d'un autre objet) , mais c'est difficile à dire car vous ne connaissez pas votre domaine. En outre, il est considéré comme une chose normale pour normaliser vos données.

43
Bloomca

La section des documents Redux sur Structuring Reducers couvre cela. En particulier, consultez la section sur Modèles de mise à jour immuables . Les exemples donnés concernent des objets et des tableaux JS simples, mais la même approche s'applique - map() sur la liste, renvoie l'élément existant pour tout ce que vous ne faites pas souhaitez mettre à jour et renvoyez une nouvelle version pour celle que vous voulez mettre à jour.

Par la documentation, notez également qu'il est plus facile de mettre à jour un élément spécifique si vos données sont stockées dans une structure normalisée, car vous pouvez les rechercher directement par ID. La section "Réducteurs structurants" couvre également la normalisation.

6
markerikson