web-dev-qa-db-de.com

Wie teilt man die Logik zwischen Redux-Reduktionen und Action-Erstellern auf?

Ich habe eine Logik, die ich in den Reducer eingefügt habe, die meiner Meinung nach möglicherweise in die Action aufgenommen und weitergegeben werden sollte.

Ist es die beste Praxis, solche Sachen in die Aktionen oder den Reduzierer zu stecken?

Arbeitsbeispiel hier .

Minderercode:

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

Ihr Reduzierer muss rein sein. Derzeit ist es nicht rein. Es ruft deal() auf, das getRandom() aufruft, das auf Math.random() beruht und daher nicht rein ist.

Diese Art von Logik („Daten generieren“, ob randomisiert oder durch Benutzereingaben) sollte im Aktionsersteller enthalten sein. Aktionsersteller müssen nicht rein sein und können Math.random() sicher verwenden. Dieser Aktionsersteller würde eine Aktion zurückgeben, ein Objekt, das die Änderung beschreibt

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

Der Reduzierer würde diese Daten einfach hinzufügen (oder ersetzen?).

Beginnen Sie im Allgemeinen mit einem Aktionsobjekt. Es sollte die Änderung so beschreiben, dass die Ausführung des Reduzierers mit dem gleichen Aktionsobjekt und dem gleichen vorherigen Status denselben nächsten Status zurückgibt. Aus diesem Grund darf der Reducer keine Math.random()-Aufrufe enthalten. Sie würden diese Bedingung unterbrechen, da sie jedes Mal zufällig wären. Sie könnten Ihren Reduzierer nicht testen.

Nachdem Sie herausgefunden haben, wie das Aktionsobjekt aussieht (z. B. wie oben), können Sie den Aktionsersteller schreiben, um es zu generieren, und einen Reduzierer, um den Status und die Aktion in den nächsten Status zu konvertieren. Die Logik zum Generieren einer Aktion beruht auf dem Aktionsersteller, die Logik, um darauf zu reagieren, liegt im Reduzierer, der Reduzierer muss rein sein.

Schließlich verwenden Sie keine Klassen innerhalb des Staates . Sie sind nicht wie gewohnt serialisierbar. Sie benötigen keine Card-Klasse. Verwenden Sie einfach Objekte und Arrays.

63
Dan Abramov

Es scheint also eine bewährte Methode zu sein, über eine statische Klasse zu verfügen, die die Entery-Punkte der ersten Ebene behandelt, die die Redux-Aktionen außerhalb des Redux instanziieren.

Ich nehme an, das macht Sinn, um die Store- und Action-Ketten rein zu halten.

Das mag auf den ersten Blick wie viel replizierter Code aussehen, aber wenn Sie mit dem Dispatchen beginnen oder von mehreren Stellen aus versenden müssen, öffnet sich der Code und ist sinnvoll.

0
Mardo

Ich verstehe, dass Aktionen einfache Objekte sein sollten, die zwei Dinge enthalten: (i) den Aktionstyp und (ii) was geändert wurde (d. H. Die neuen Daten).

Reduktionen sind dagegen reine Funktionen, die Aktionen und den vorherigen App-Status als Eingaben übernehmen und den neuen App-Status zurückgeben. Wie sie das schaffen, liegt an Ihnen. Sie können die erforderliche Logik hinzufügen, um die Kombination aus vorherigem Status + Aktion zu übernehmen und den neuen Status zurückzugeben, solange Sie keine Daten außerhalb Ihrer Reduktionsfunktionen mutieren.

Ich bin mir nicht sicher, ob die Funktion deal() zu einer Aktion oder einem Reduzierer gehört. Ich denke, ein besserer Ort könnte in einer Art Event-Handler sein (z. B. onClick). Sie können dann die Ergebnisse des Deal-Aufrufs als Aktion an Ihren Reducer weiterleiten. 

0
Mark McKelvy