web-dev-qa-db-fra.com

Où puis-je récupérer les données initiales du serveur dans une React application Redux?

J'ai commencé à apprendre React/Redux et je suis tombé sur une question qui est probablement une question très fondamentale. Vous trouverez ci-dessous des extraits de mon application avec du code supprimé pour des raisons de simplicité.

Mon état est décrit par un tableau de sites vide par défaut. Le réducteur suivant aura l’action LOAD_SITES Pour charger un ensemble de sites différent chaque fois que l’utilisateur paginera sur une page différente, mais pour l’instant il ne fait rien. React commence par rendre PublishedSitesPage qui restitue ensuite PublishedSitesBox, qui effectue ensuite une boucle sur les données et rend les sites individuels.

Ce que je veux faire, c'est le rendre tout avec le tableau vide par défaut et, dans l'intervalle, initier une promesse de "charger les sites depuis le serveur" et, une fois qu'il est résolu, l'action dispatch LOAD_SITES. Quelle est la meilleure façon de faire cet appel? Je pensais au constructeur de PublishedSitesBox ou peut-être à componentDidMount. Mais je ne suis pas sûr que cela fonctionne. Mon souci est de créer de cette manière une boucle sans fin qui conservera le rendu. J'imagine que je pourrais empêcher cette boucle sans fin en ayant un autre paramètre d'état du type "haveRequestedInitialData". Une autre idée que j'ai eu est de simplement faire cette promesse juste après avoir fait ReactDOM.render(). Quelle est la meilleure et la plus propre façon de procéder?

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
});
47
Eugene

Il n’ya aucune raison pour que cette logique de chargement de données touche vos React). Ce que vous voulez ici, c’est que la promesse d’envoyer une action à vos réducteurs soit renvoyée, ce qui apporte les modifications appropriées à le magasin, ce qui provoque alors un nouveau rendu des composants React) selon les besoins.

(Peu importe que vous lanciez l'appel asynchrone avant ou après avoir appelé ReactDOM.render; la promesse fonctionnera dans les deux sens)

Quelque chose comme ça:

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]
);

Vos composants React sont des consommateurs de votre magasin, mais il n’existe aucune règle selon laquelle ils doivent être les SEUL consommateurs de votre magasin.

40
S McCrohan