2016-04-22 13 views
31

Ho iniziato a imparare React/Redux e sono incappato in qualcosa che è probabilmente una domanda di base. Di seguito sono riportati i frammenti della mia app con un codice rimosso per motivi di semplicità.Dove posso recuperare i dati iniziali dal server in un'app React Redux?

Il mio stato è descritto da una serie di siti che è vuota per impostazione predefinita. Il riduttore successivo avrà l'azione LOAD_SITES per caricare un insieme diverso di siti ogni volta che l'utente impagina una pagina diversa ma per ora non sta facendo nulla. React inizia con il rendering PublishedSitesPage che quindi esegue il rendering di PublishedSitesBox che quindi esegue il loop dei dati e il rendering dei singoli siti.

Quello che voglio fare è renderizzare tutto con la matrice vuota predefinita e nel frattempo avviare una promessa "carica siti dal server" e una volta risolta, inviare l'azione LOAD_SITES. Qual è il modo migliore per effettuare questa chiamata? Stavo pensando a qualsiasi costruttore di PublishedSitesBox o forse componentDidMount. Ma non sono sicuro che funzioni, la mia preoccupazione è che creerò un ciclo infinito in questo modo che manterrà il re-rendering. Immagino di poter evitare questo ciclo infinito in qualche modo avendo qualche altro param di stato sulla falsariga di "haveRequestedInitialData". Un'altra idea che ho è quella di fare semplicemente questa promessa subito dopo aver fatto ReactDOM.render(). Qual è il modo migliore e più pulito per farlo?

export default function sites(state = [], action) { 
    switch (action.type) { 
    default: 
     return state; 
    } 
} 
... 

const publishedSitesPageReducer = combineReducers({ 
    sites 
}); 

ReactDOM.render(
    <Provider store={createStore(publishedSitesPageReducer)}> 
    <PublishedSitesPage /> 
    </Provider>, 
    this.$view.find('.js-published-sites-result-target')[0] 
); 

... 

export default function PublishedSitesPage() { 
    return (
    <PublishedSitesBox/> 
); 
} 

... 

function mapStateToProps(state) { 
    return { sites: state.sites }; 
} 

const PublishedSitesBox = connect(mapStateToProps)(({sites}) => { 
    // render sites 
}); 

risposta

29

Non c'è motivo per questa logica di caricamento dei dati di toccare i componenti React. Quello che vuoi qui è per il ritorno della promessa di inviare un'azione ai tuoi riduttori, che apportano le modifiche appropriate allo store, che a sua volta fa ri-renderizzare i componenti di React come appropriato.

(Non importa se dare il via alla chiamata asincrona prima o dopo la chiamata ReactDOM.render, la promessa funziona in entrambi i casi)

Qualcosa di simile a questo:

var store = createStore(publishedSitesPageReducer); 

someAsyncCall().then(function(response) { 
    store.dispatch(someActionCreator(response)); 
}); 

ReactDOM.render(
    <Provider store={store}> 
    <PublishedSitesPage /> 
    </Provider>, 
    this.$view.find('.js-published-sites-result-target')[0] 
); 

tuo Reagire i componenti sono consumatori del tuo negozio, ma non c'è alcuna regola che debbano essere gli unici consumatori del tuo negozio.

+0

Grazie, sì, questo ha senso e questo è stato uno dei modi in cui stavo pensando di andare, ma non ero sicuro se fosse il modo previsto di farlo o se ci fosse una sorta di magia di "stato di default di recupero" nascosta in un framework react/redux da qualche parte. Lo proveremo domani e vedremo se funziona e sembra buono! – Eugene

+1

Una delle cose meravigliose di un negozio Redux è che può essere in realtà la stanza di compensazione comune per i dati provenienti da una varietà di luoghi. Ad esempio, i socket Web per le origini dati live remote possono essere azioni di distribuzione che aggiornano il tuo negozio senza input da parte dell'utente e l'interfaccia utente non ha bisogno di sapere o preoccuparsi da dove proviene il nuovo stato. –

+0

Ovviamente il creatore dell'azione potrebbe invece fare la richiesta asincrona. –

-4

V'è un chiaro esempio qui su come farlo: Facebook Tutorial

Per quanto riguarda il ciclo senza fine, una volta la matrice non è più vuota, Cancella l'intervallo. Ciò dovrebbe impedire il ciclo.

+2

Grazie per la risposta, ma ho già letto quel tutorial ed è molto buono, ma descrive il recupero dei dati solo per React. Quello che sto cercando di fare è recuperare i dati in un'app in cui React è in bundle con Redux, dove i dati (stato dell'app) dovrebbero essere separati dai componenti React. – Eugene

Problemi correlati