React / Redux – envoie des actions sur app load / init

J’ai une authentification par jeton d’un serveur, alors lorsque mon application Redux est chargée au départ, je dois demander à ce serveur de vérifier si l’utilisateur est authentifié ou non et si oui, je devrais obtenir un jeton.

J’ai trouvé que l’utilisation des actions INIT de base de Redux n’est pas recommandée, alors comment puis-je envoyer une action avant que l’application soit rendue?

Vous pouvez dissortingbuer une action dans la méthode Racine componentDidMount et dans la méthode de render , vous pouvez vérifier le statut de l’authentification.

Quelque chose comme ça:

 class App extends Component { componentDidMount() { this.props.getAuth() } render() { return this.props.isReady ? 
ready
:
not ready
} } const mapStateToProps = (state) => ({ isReady: state.isReady, }) const mapDispatchToProps = { getAuth, } export default connect(mapStateToProps, mapDispatchToProps)(App)

Je n’ai pas été heureux avec les solutions qui ont été proposées pour cela, et je me suis alors rendu compte que je pensais aux cours devant être rendus. Qu’en est-il si je viens de créer une classe pour le démarrage, puis de pousser les choses dans la méthode componentDidMount et que le render affiche simplement un écran de chargement?

          

Et puis quelque chose comme ça:

 class Startup extends Component { static propTypes = { connection: PropTypes.object } componentDidMount() { this.props.actions.initialiseConnection(); } render() { return this.props.connection ? this.props.children : (

Loading...

); } } function mapStateToProps(state) { return { connection: state.connection }; } function mapDispatchToProps(dispatch) { return { actions: bindActionCreators(Actions, dispatch) }; } export default connect( mapStateToProps, mapDispatchToProps )(Startup);

Ensuite, écrivez des actions de redux pour asynchroniser l’initialisation de votre application. Fonctionne un régal.

Mise à jour : Cette réponse est pour React Router 3

J’ai résolu ce problème en utilisant les accessoires de réacteurs sur routeur. Voici comment le code ressemble à:

 // this function is called only once, before application initially starts to render react-route and any of its related DOM elements // it can be used to add init config settings to the application function onAppInit(dispatch) { return (nextState, replace, callback) => { dispatch(performTokenRequest()) .then(() => { // callback is like a "next" function, app initialization is stopped until it is called. callback(); }); }; } const App = () => (   
);

Utilisation de: Apollo Client 2.0, React-Router v4, React 16 (Fibre)

La réponse sélectionnée utilise l’ancien React Router v3. Je devais faire «dispatch» pour charger les parameters globaux de l’application. L’astuce consiste à utiliser componentWillUpdate, bien que l’exemple utilise un client apollo, et que ne pas récupérer les solutions est équivalent. Vous n’avez pas besoin de boucle de

SettingsLoad.js

 import React, { Component } from 'react'; import { connect } from 'react-redux'; import {bindActionCreators} from "redux"; import { graphql, compose, } from 'react-apollo'; import {appSettingsLoad} from './actions/appActions'; import defQls from './defQls'; import {resolvePathObj} from "./utils/helper"; class SettingsLoad extends Component { constructor(props) { super(props); } componentWillMount() { // this give infinite loop or no sense if componente will mount or not, because render is called a lot of times } //componentWillReceiveProps(newProps) { // this give infinite loop componentWillUpdate(newProps) { const newrecord = resolvePathObj(newProps, 'getOrgSettings.getOrgSettings.record'); const oldrecord = resolvePathObj(this.props, 'getOrgSettings.getOrgSettings.record'); if (newrecord === oldrecord) { // when oldrecord (undefined) !== newrecord (ssortingng), means ql is loaded, and this will happens // one time, rest of time: // oldrecord (undefined) == newrecord (undefined) // nothing loaded // oldrecord (ssortingng) == newrecord (ssortingng) // ql loaded and present in props return false; } if (typeof newrecord ==='undefined') { return false; } // here will executed one time setTimeout(() => { this.props.appSettingsLoad( JSON.parse(this.props.getOrgSettings.getOrgSettings.record)); }, 1000); } componentDidMount() { //console.log('did mount this props', this.props); } render() { const record = resolvePathObj(this.props, 'getOrgSettings.getOrgSettings.record'); return record ? this.props.children : (

...

); } } const withGraphql = compose( graphql(defQls.loadTable, { name: 'loadTable', options: props => { const optionsValues = { }; optionsValues.fetchPolicy = 'network-only'; return optionsValues ; }, }), )(SettingsLoad); const mapStateToProps = (state, ownProps) => { return { myState: state, }; }; const mapDispatchToProps = (dispatch) => { return bindActionCreators ({appSettingsLoad, dispatch }, dispatch ); // to set this.props.dispatch }; const ComponentFull = connect( mapStateToProps , mapDispatchToProps, )(withGraphql); export default ComponentFull;

App.js

 class App extends Component { render() { return (        

Similaire, mais une alternative à ce qui précède (cela ne semble fonctionner qu’avec React-Router v3):

Routes.js

 import React from 'react'; import { Route, IndexRoute } from 'react-router'; import App from '../components/App'; import Home from '../views/Home'; import OnLoadAuth from '../containers/app/OnLoadAuth'; export default = (   {* Routes that require authentication *}  ); 

OnLoadAuth.js

 import React, { Component } from 'react'; import { connect } from 'react-redux'; import { authenticateUser, fetchingUser } from '../../actions/AuthActionCreators'; import Spinner from '../../components/loaders/Spinner'; export default App => { class OnLoadAuth extends Component { componentDidMount = () => this.props.authenticateUser(); render = () => ( (this.props.isLoading === undefined || this.props.isLoading) ?  :  ) } return connect( state => ({ isLoading: state.auth.fetchingUser }), { authenticateUser, fetchingUser } )(OnLoadAuth); };