web-dev-qa-db-fra.com

Comment diviser la logique entre les réducteurs Redux et les créateurs d'action?

J'ai une certaine logique dans le réducteur que je pense devrait être éventuellement mise dans l'action et transmise?

Est-ce la meilleure pratique de mettre ce genre de choses dans les actions ou les réducteurs?

Exemple de travail ici .

Code réducteur:

function Card() {
  this.card = (Math.random()*4).toFixed(0);
}

Card.prototype = {
  getRandom: function(){
    var card;
    //console.log(this.card)
    switch (this.card) {
      case '1':
      card = 'heart';
      break;
      case '2':
      //card = 'diamonds';
      card = 'heart'; // weight the odds abit
      break;
      case '3':
      card = 'club';
      break;
      case '4':
      card = 'spade';
      break;
      default:
      card = 'heart';
      break;
    }
    return card;
  }
}

var dealer = {
  deal: function(){
    var results = [];
    for(var i = 0; i <4; i++){
      var card = new Card();
      results.Push(card.getRandom());
    }
    console.log(results);
    return results;
  }
}


const initialState = {
  count: 0,
  data: []
}

function counter (state = initialState, action) {
  let count = state.count
  switch (action.type) {
    case 'increase':
      return Object.assign({}, state, {
        data: dealer.deal(),
        count: state.count+1
      })
    default:
      return state
  }
}
29
user3224271

Votre réducteur doit être pur. Actuellement, ce n'est pas pur. Il appelle deal() qui appelle getRandom() qui s'appuie sur Math.random() et n'est donc pas pur.

Ce type de logique («générer des données», de manière aléatoire ou à partir d'une entrée utilisateur) devrait être dans le créateur de l'action. Les créateurs d’action n’ont pas besoin d’être pur et peuvent utiliser en toute sécurité Math.random(). Ce créateur d'action renverrait une action, un objet décrivant le changement

{
  type: 'DEAL_CARDS',
  cards: ['heart', 'club', 'heart', 'heart']
}

Le réducteur ajouterait simplement (ou remplacerait?) Ces données à l'intérieur de l'état.

En général, commence avec un objet d'action. Il devrait décrire le changement de manière à ce que l'exécution du réducteur avec le même objet d'action et le même état précédent renvoie le même état suivant. C'est pourquoi réducteur ne peut pas contenir d'appels Math.random() - ils briseraient cette condition, car ils seraient aléatoires à chaque fois. Vous ne pourriez pas tester votre réducteur.

Après avoir déterminé l'apparence de l'objet d'action (comme ci-dessus), vous pouvez écrire au créateur de l'action pour le générer, ainsi qu'à un réducteur pour transformer l'état et l'action en état suivant. La logique pour générer une action réside dans le créateur de l'action, la logique pour y réagir réside dans le réducteur, réducteur doit être pur.

Enfin, n’utilisez pas de classes dans l’état . Ils ne sont pas sérialisables tels quels. Vous n’avez pas besoin d’une classe Card. Utilisez simplement des objets simples et des tableaux.

63
Dan Abramov

Il semble donc préférable de disposer d'une classe statique qui gère les points d'entery de premier niveau qui instancient les actions de redux en dehors du redux.

Je suppose que cela a du sens de garder les chaînes de magasin et d’action pures.

Cela peut ressembler à beaucoup de code répliqué au début, mais lorsque vous commencez à distribuer en fonction de conditions ou que vous devez envoyer à partir de plusieurs emplacements, cela commence à s’ouvrir et à prendre un sens.

0
Mardo

Je crois comprendre que les actions doivent être de simples objets contenant deux éléments: (i) le type d’action et (ii) ce qui a changé (c’est-à-dire les nouvelles données).

Les réducteurs, d’autre part, sont des fonctions pures qui effectuent des actions et l’état de l’application précédente en tant qu’entrées et renvoient le nouvel état de l’application. La façon dont ils accomplissent cela dépend de vous. Vous pouvez ajouter la logique nécessaire pour combiner état précédent + action et renvoyer le nouvel état tant que vous ne modifiez pas les données en dehors de votre ou vos fonctions de réduction.

En ce qui concerne votre code en particulier, je ne suis pas sûr que la fonction deal() appartienne à une action ou à un réducteur. Je pense qu'un meilleur endroit pourrait être dans une sorte de gestionnaire d'événements (par exemple onClick). Vous pouvez ensuite transmettre les résultats de l’appel à la transaction en tant qu’action à votre réducteur. 

0
Mark McKelvy