2015-12-04 33 views
28

Ho qualche logica che ho inserito nel riduttore che penso possa essere inserito nell'Azione e trasmesso?Come dividere la logica tra riduttori di Redux e creatori di azioni?

È consigliabile inserire questo tipo di elementi nelle azioni o nel riduttore?

Esempio di lavoro here.

codice Reducer:

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

Riduttori devono contenere la logica per mutare lo Stato, ma è meglio la pratica di non scrivere questo all'interno l'istruzione switch, ma estrarre la logica per una funzione separata passando il CurrentState e restituendo il nuovo stato. Un ottimo tutorial: http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html#loading-entries – JensDebergh

+0

"I riduttori dovrebbero contenere la logica per la modifica dello stato"? – user3224271

+0

Il riduttore dovrebbe contenere tutta la logica per mutare lo stato dato. Ma è delle migliori pratiche per estrarre questa logica di separare le funzioni, invece di scriverlo in linea tra dichiarazioni caso per esempio: '' 'tornare ADDUSERS (CurrentState, azione) -> newState''' – JensDebergh

risposta

57

Il tuo riduttore deve essere puro. Attualmente non è puro. Chiama deal() che chiama getRandom() che si basa su Math.random() e quindi non è puro.

Questo tipo di logica ("generazione di dati", sia casuale o di input dell'utente) dovrebbe essere nel creatore di azioni. I creatori di azioni non devono essere puri e possono tranquillamente utilizzare Math.random(). Questo creatore azione sarebbe tornato un'azione, un oggetto che descrive il cambiamento: (? O sostituire)

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

Il riduttore sarebbe solo aggiungere questi dati all'interno dello Stato.

In generale, inizia con un oggetto azione. Dovrebbe descrivere il cambiamento in modo tale che l'esecuzione del riduttore con lo stesso oggetto azione e lo stesso stato precedente dovrebbe restituire lo stesso stato successivo. Questo è il motivo per cui il riduttore non può contenere le chiamate Math.random(): potrebbero rompere questa condizione, in quanto sarebbero casuali ogni volta. Non saresti in grado di testare il tuo riduttore.

Dopo aver scoperto come appare l'oggetto azione (ad esempio, come sopra), è possibile scrivere l'action creator per generarlo e un riduttore per trasformare lo stato e l'azione nello stato successivo. La logica per generare un'azione risiede nel creatore dell'azione, la logica per reagire ad essa risiede nel riduttore, il riduttore deve essere puro.

Infine, non utilizzare classi all'interno dello stato. Non sono serializzabili come sono. Non hai bisogno di una classe Card. Usa solo oggetti e matrici semplici.

+0

Qual è la logica dietro la generazione di azioni nei creatori di azioni? Cosa succede se quella logica è memorizzata nel riduttore? (Suppongo che la logica sia pura) Cosa c'è di sbagliato in questo? Ho dato un'occhiata alla documentazione di redux + elm e non ho trovato alcun riferimento ad esso. Ti dispiacerebbe elaborare/indicarmi il doc giusto? – danielepolencic

+0

@danielepolencic Temo che questa è una domanda vaga. Se offri un esempio specifico, sarò felice di discuterne. –

+3

@danielepolencic se la logica è il creatore azione, quindi riprodurre le azioni create sempre produrrà stesso stato. Se la logica è nel riduttore, i risultati della riproduzione delle azioni non sono garantiti uguali. Che non può importa, in alcuni casi, ma è necessario se si desidera gli strumenti redux dev per lavorare bene. –

0

mia comprensione è che le azioni dovrebbero essere semplici oggetti che contengono due cose: (i) il tipo di azione e (ii) che cosa è cambiato (cioè i nuovi dati).

I riduttori, d'altra parte, sono funzioni pure che eseguono azioni e lo stato dell'app precedente come input e restituiscono il nuovo stato dell'app. Come lo fanno dipende da te. È possibile aggiungere qualsiasi logica necessaria per prendere la combinazione dello stato precedente + azione e restituire il nuovo stato a condizione che non vengano modificati i dati al di fuori delle funzioni del riduttore.

Per quanto riguarda specificamente il codice, non sono sicuro che la funzione deal() appartenga a un'azione oa un riduttore. Penso che un posto migliore potrebbe essere in una sorta di gestore di eventi (ad esempio onClick). È quindi possibile passare i risultati dell'invito come un'azione al riduttore.

+0

dispiace solo per elaborare: Non ho significa all'interno dell'azione, intendevo con il codice di azione (nel modulo). Sto iniziando a pensare possibile in una sorta di modulo utils? – user3224271

+0

Sì, mi piace mantenere i miei moduli di azioni piuttosto semplici. Fondamentalmente solo un gruppo di funzioni che restituiscono il tipo e i nuovi dati. Come vengono derivati ​​i nuovi dati viene da altrove. –

0

Sembra quindi una buona pratica avere una classe statica che gestisca i punti entery di primo livello che istanzia le azioni di ridondanza al di fuori del redux.

suppongo che abbia un senso per tenere le catene di negozi e di azione pura.

Questo potrebbe sembrare un sacco di codice replicato in un primo momento, ma quando si avvia dispatching in base alle condizioni o la necessità di inviare da più posizioni inizia ad aprire e ha senso.

Problemi correlati