2016-03-15 23 views
5

Ho usato Redux nella mia app React e qualcosa mi ha infastidito. La documentazione di Redux rende molto chiaro che il riduttore dovrebbe essere libero dallo stato. Si vedono spesso esempi come questo:Perché un riduttore Redux deve essere privo di effetti collaterali?

function reducer(state = { exampleState: true }, action) { 
    switch(action.type) { 
    case "ACTION_EXAMPLE": 
    return Object.assign({}, state, { exampleState: false }); 
    default: 
    return state; 
    } 
} 

La mia domanda è perché è necessario? JavaScript è single threaded. Non c'è possibilità di una condizione di gara all'interno del riduttore. Per quanto posso dire, un negozio Redux è solo in grado di restituire lo stato attuale del negozio, quindi sembra strano che ci sia così tanta attenzione sulle funzioni pure.

+1

Scusa, cosa significa "non c'è possibilità di una condizione di competizione all'interno del riduttore"? – FurkanO

+0

https://goshakkk.name/redux-side-effect-approaches/ – zloctb

risposta

6

Il caso per le funzioni di puro è fatto in l'autore del documentation. Certo, puoi scrivere riduttori con funzioni impure, ma:

Le funzionalità di sviluppo come la corsa nel tempo, la registrazione/riproduzione o il ricaricamento a caldo si interrompono.

Se nessuna di queste caratteristiche fornisce un vantaggio o è di interesse, quindi, con tutti i mezzi, scrivere le funzioni impure. Tuttavia, la domanda allora diventerebbe, perché usare Redux?

+0

Grazie Brett, non ero a conoscenza di quelle caratteristiche. – Max

2

Solo perché è a thread singolo non significa che non sia asincrono, ma questo è davvero il punto. Gli effetti collaterali non hanno nulla a che fare con il threading e tutto ciò che riguarda il fatto che il proprio oggetto si comporti nel modo in cui la sua API dice che: Se avesse stato, si potrebbe avere un comportamento diverso a seconda di quante chiamate sono state fatte ad esso e quali dati sono stati passato per ogni chiamata, invece di essere un oggetto con comportamento costante indipendentemente da quando lo chiami.

La parte importante è "si comportano sempre esattamente allo stesso modo per esattamente lo stesso input". Aggiungere e usare lo stato è quasi letteralmente una promessa che non sarà così.

+0

Siamo spiacenti, questo non risponde alla domanda. Tutte queste cose sono possibili modificando la directory di stato. Si consideri un riduttore che fa questo: '(state, action) => {state.prop + = 1; stato di ritorno; } '. Questo non è privo di effetti collaterali, ma avrà un comportamento diverso a seconda di quante chiamate sono state fatte. – Max

+0

Hai appena letteralmente descritto un effetto collaterale imprevedibile. Hai appena aggiornato un oggetto che il negozio non possiede: cosa è successo al proprietario dell'oggetto? Il valore di 'prop' è magicamente cambiato, quali sono le conseguenze di ciò? Perché dovresti pensare di sapere se anche altri oggetti potrebbero farlo, incluso il codice di cui non sai nulla (moduli, ecc.)? Non scrivere codice con effetti collaterali, perché nella migliore delle ipotesi tu, ma nella peggiore delle ipotesi tutti usano il tuo codice, non comprenderanno le ripercussioni di questi e non saranno in grado di fare affidamento sul codice che si comporta deterministicamente prevedibile –

+0

@Max " avrà un comportamento diverso a seconda di quante chiamate sono state fatte "Se ogni singola chiamata che è stata effettuata, con lo stesso input cambia lo stato nello stesso modo prevedibile e riproducibile, non ha effetti collaterali. EDIT: inoltre, non si dovrebbe mai operare sull'oggetto stato stesso.Questo è un no –

1

Perché

Redux is a predictable state container for JavaScript apps.

accento sulla 'prevedibile'.

Aggiunta di effetti collaterali rende un prevedibile

+1

Puoi aggiungere qualche giustificazione su come il comportamento potrebbe diventare imprevedibile? – Max

+0

Ok. Diciamo che, per qualsiasi motivo, aggiungi un XHRequest nel tuo riduttore, che in caso di successo, apporta modifiche allo 'stato'. Hai appena reso imprevedibile il tuo riduttore, perché ora non puoi garantire che ogni volta che il riduttore viene eseguito con lo stesso input esatto, cambierà sempre lo stato nello stesso modo prevedibile. (Perché cosa succede se l'XHRequest fallisce?) –

+0

Certo, non si vorrebbe fare una chiamata AJAX in un riduttore. Ma ciò non significa che il riduttore ** deve ** essere privo di effetti collaterali. Il tuo esempio mostra che il riduttore dovrebbe essere deterministico. – Max

Problemi correlati