1
votes

Ce réducteur de redux est-il OK

Ce réducteur est-il OK:

function someReducer(state = initialState, action) {
   if (action.type === SOME_ACTION) {
      const newState = Object.assign( {}, state );
      // ...
      // doing whatever I want with newState 
      // ...
      return newState;
   }   
   return state;
}

et si c'est OK, pourquoi nous avons besoin de toutes ces bibliothèques immuables pour nous compliquer la vie.

p.s J'essaie juste de comprendre Redux et l'immuabilité


6 commentaires

Avec quelle partie avez-vous une question? SO n'est pas pour les révisions de code


@ristepan Je suggérerais de lui demander de réagir reddit . Vous pouvez ne pas attirer l'attention sur cela même si c'est une bonne question valable ici. SO a beaucoup de règles. Mieux vaut aller demander à des endroits plus flexibles comme je l'ai mentionné.


Pour le clonage profond, nous devons utiliser d’autres alternatives car Object.assign () copie les valeurs des propriétés. Si la valeur source est une référence à un objet, elle ne copie que cette valeur de référence.


La question @JuanMendes est claire.


assign n'est pas un clone profond, vous pouvez donc toujours accéder à l'état et le modifier directement.


@ArupRakshit Il existe plusieurs solutions, c'est une question de goût. Désolé, mais oui, SO a ses règles et oui, le code existant est OK tant que l'OP ne modifie pas les sous-objets.


4 Réponses :


3
votes

L'approche standard consiste à utiliser un commutateur / cas avec une syntaxe de propagation ( ... ) dans votre réducteur.

export default function (state = initialState, action) {
  switch (action.type) {
    case constants.SOME_ACTION:
      return {
        ...state,
        newProperty: action.newProperty
      };

    case constants.ERROR_ACTION:
      return {
        ...state,
        error: action.error
      };

    case constants.MORE_DEEP_ACTION:
      return {
        ...state,
        users: {
          ...state.users,
          user1: action.users.user1
        }
      };

    default:
      return {
        ...state
      }
  }
}

Vous pouvez ensuite utiliser la syntaxe de diffusion ES6 pour renvoyer votre ancien état avec les nouvelles propriétés que vous souhaitez modifier / ajouter.

Vous pouvez en savoir plus sur cette approche ici ... https://redux.js.org/recipes/using-object-spread- opérateur


3 commentaires

Notant que ... est aussi un clone superficiel, et peut ne pas être suffisant.


C'est à peu près la même approche je pense, je comprends maintenant assigner n'est pas une copie complète complète.


Oui, j'ai également ajouté une mise à jour de propriété imbriquée à ma réponse afin que vous puissiez voir un exemple de mise à jour d'une propriété imbriquée.



-2
votes

Si votre état a des objets ou des tableaux imbriqués, Object.assign ou ... copiera les références à votre ancienne variable d'état et cela peut causer des problèmes. C'est la raison pour laquelle certains développeurs utilisent des bibliothèques immuables car dans la plupart des cas, l'état a un tableau ou des objets imbriqués profonds.

function someReducer(state = initialState, action) {
   if (action.type === SOME_ACTION) {
       const newState = Object.assign( {}, state );
       // newState can still have references to your older state values if they are array or orobjects

      return newState;
   }   
   return state;
}


5 commentaires

Vous venez de copier sa question, il n'y a pas de réponse ici.


@rrd Je pense que le commentaire intégré est censé être la réponse.


Les réponses doivent être évidentes et visibles sans défilement.


J'ai maintenant également expliqué la raison.


Après tout, je pense que quelque chose comme la fonction deepassig fera l'affaire, du moins pour moi. J'aime la bibliothèque immer



5
votes

export default function (state = initialState, action) {

  const actions = {
    SOME_ACTION: () => {
      return {
        ...state
      }
    },
    ANOTHER_ACTION: () => {
      return {
        ...state
        error: action.error
      }
    },
    DEFAULT: () => state;
  }
  
  return actions[action.type] ? actions[action.type]() : actions.DEFAULT(); 
}

Je préfère faire ça à la place. Je ne suis pas un grand fan des instructions switch.


8 commentaires

Première fois à voir ce flux. Savoureux!


Vérifiez ceci: medium.com/chrisburgin/…. Il contient plus d'exemples et d'explications.


Agréable! Merci mec.


J'aime ça et je vais l'essayer


Est-ce correct? Autant que je sache, il ne retourne pas un nouvel état, il renvoie une fonction d'un nouvel état. De plus, il recrée tout l'objet actions à chaque exécution de la fonction de réduction - il serait préférable que les actions soient définies en dehors du réducteur.


Les actions sont en dehors du réducteur. L'objet remplace simplement l'instruction switch, la fonction renvoie l'état lui-même et en accédant aux objets avec la notation par points, c'est bien mieux que d'avoir une instruction switch.


@NicolaeMaties Non, il renvoie une fonction, la constante actions est définie à l'intérieur du réducteur et contient des fonctions de réducteur lui-même qui fonctionnent sur les fermetures et préférer les objets aux instructions de commutation est très subjective.


Vous avez raison, il fallait juste l'appel, je l'ai édité.



0
votes

J'ai trouvé quelque chose que j'aime beaucoup:

 import createReducer from 'redux-starter-kit';
 const someReducer = createReducer( initialState, {
    SOME_ACTION: (state) => { /* doing whatever I want with this local State */ },
    SOME_ANOTHER_ACTION: (state) => { /* doing whatever I want with local State */ },
    THIRD_ACTION: (state, action) => { ... }, 
 });


0 commentaires