2015-12-04 4 views
28

Ich habe eine Logik, die ich in den Reducer gesetzt habe, von dem ich denke, dass er möglicherweise in die Action gesteckt und weitergegeben werden sollte?Wie teilt man die Logik zwischen Redux Reducern und Action Creators auf?

Ist es die beste Vorgehensweise, diese Art von Material in die Aktionen oder den Reducer zu legen?

Arbeitsbeispiel here.

Reducer Code:

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 
    } 
} 
+1

Reduzierer sollten die Logik für die Mutation des Zustands enthalten, aber es ist die beste Vorgehensweise, dies nicht in die switch -Anweisung zu schreiben, sondern die Logik in eine separate Funktion zu extrahieren, die den aktuellen Status übergibt und den neuen Status zurückgibt. Ein tolles Tutorial: http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html#loading-entries – JensDebergh

+0

"Reducers sollte die Logik für die Mutation des Staates enthalten"? – user3224271

+0

Der Reduzierer sollte alle Logik enthalten, um den gegebenen Zustand zu verändern. Aber es ist die beste Vorgehensweise, diese Logik in separate Funktionen zu extrahieren, anstatt sie zwischen case-Anweisungen inline zu schreiben. Beispiel: '' 'addUsers (currentState, action) zurückgeben -> newState''' – JensDebergh

Antwort

57

Ihr Reduzierstück muss rein sein. Derzeit ist es nicht rein. Es ruft deal(), die getRandom() ruft, die auf Math.random() beruht und somit nicht rein ist.

Diese Art von Logik ("Generieren von Daten", ob randomisiert oder von Benutzereingaben) sollte im Aktionsersteller sein. Action-Ersteller müssen nicht rein sein und können Math.random() sicher verwenden. Diese Aktion Schöpfer würde eine Aktion zurückkehren, ein Objekt beschreibt die Änderung: (oder ersetzen)

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

Das Reduktionsmittel würde nur hinzufügen, diese Daten innerhalb des Staates.

Im Allgemeinen beginnt mit einem Aktionsobjekt. Die Änderung sollte so beschrieben werden, dass der Reduzierer mit dem gleichen Aktionsobjekt und dem gleichen vorherigen Zustand denselben nächsten Zustand zurückgibt. Deshalb kann der Reduzierer keine Math.random() Aufrufe enthalten - sie würden diesen Zustand brechen, da sie jedes Mal zufällig sind. Sie könnten Ihren Reducer 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 Status und Aktion in den nächsten Zustand zu transformieren. Die Logik zum Generieren einer Aktion befindet sich im Aktionsersteller, die Logik, die darauf reagiert, befindet sich im Reduzierer, der Reduzierer muss rein sein.

Schließlich keine Klassen im Zustand verwenden. Sie sind nicht serialisierbar wie sie sind. Sie benötigen keine Card Klasse. Verwenden Sie nur einfache Objekte und Arrays.

+0

Welche Logik hat es, Aktionen in den Aktionserstellern zu generieren? Was passiert, wenn diese Logik im Reduktor gespeichert wird? (Ich gehe davon aus, dass Logik rein ist) Was ist daran falsch? Ich habe mir die Dokumentation von redux + elm angeschaut und konnte keinen Hinweis darauf finden. Würde es Ihnen etwas ausmachen, mich auf das richtige Dokument hinzuweisen? – danielepolencic

+0

@danielepolencic Ich fürchte, das ist eine vage Frage. Wenn Sie ein bestimmtes Beispiel anbieten, werde ich gerne darüber diskutieren. –

+3

@danielepolencic Wenn die Logik im Aktions-Creator enthalten ist, führt das erneute Abspielen der erstellten Aktionen immer zum selben Status. Wenn sich die Logik im Reduzierer befindet, ist nicht garantiert, dass die Ergebnisse der Wiedergabe der Aktionen identisch sind. Das kann in einigen Fällen nicht wichtig sein, aber es ist erforderlich, wenn Sie möchten, dass die Redux-Dev-Tools gut funktionieren. –

0

Mein Verständnis ist, dass die Maßnahmen einfache Objekte sein sollte, die zwei Dinge enthalten: (i) der Aktionstyp und (ii), was sich geändert (das heißt, die neuen Daten).

Reduzierer auf der anderen Seite sind reine Funktionen, die Aktionen und den vorherigen App-Status als Eingaben übernehmen und den neuen App-Status zurückgeben. Wie sie das erreichen, liegt an dir. Sie können die Logik hinzufügen, die erforderlich ist, um die Kombination aus vorherigem Zustand + Aktion zu verwenden, und den neuen Status zurückgeben, solange Sie keine Daten außerhalb Ihrer Reduzierungsfunktion (en) mutieren.

Wie für Ihren Code speziell, bin ich nicht sicher, ob die deal() Funktion entweder in einer Aktion oder einem Reducer gehört. Ich denke, ein besserer Ort könnte in einer Art Event-Handler sein (z.B. onClick). Sie könnten dann die Ergebnisse des Deal Call als eine Aktion an Ihren Reducer übergeben.

+0

Entschuldigung, nur um zu erläutern: ich tat es nicht meine in der Aktion, ich meinte mit dem Action-Code (im Modul). Ich fange an zu denken, dass es möglich ist, in einem Modul zu arbeiten? – user3224271

+0

Ja, ich möchte meine Aktionsmodule sehr einfach halten. Im Grunde nur eine Reihe von Funktionen, die den Typ und neue Daten zurückgeben. Wie diese neuen Daten herkommen, kommt anderswo vor. –

0

Es scheint dann eine Best Practice zu sein, eine statische Klasse zu haben, die die Entery-Punkte der ersten Ebene behandelt, die die Redux-Aktionen außerhalb des Redux instanziiert.

Ich denke, dass es sinnvoll ist, die Speicher- und Aktionsketten rein zu halten.

Dies könnte zunächst wie viel replizierter Code aussehen, aber wenn Sie beginnen, basierend auf Bedingungen zu versenden oder von mehreren Orten aus zu versenden, beginnt es sich zu öffnen und macht Sinn.

Verwandte Themen