web-dev-qa-db-fra.com

En attente de la fin de l'action dans React Redux

Je suis nouveau sur react et redux et j'explore en quoi il diffère de angular.

J'essaie de faire une simple page de connexion et je n'arrive pas à réaliser ce que je veux. Une fois que j'ai obtenu le nom d'utilisateur et le mot de passe d'un formulaire de connexion, je le soumets comme ci-dessous:

  submitHandler(e){
    e.preventDefault();
    var user = {
      name : this.state.username,
      password: this.state.password
    }
    this.props.authenticateUser(user);
    browserHistory.Push('/home');
    this.setState({
      username:'',
      password:''
    })
  }

Ici, authenticateUser est une fonction à l'intérieur de mon réducteur (illustré ci-dessous) qui vérifie à partir de la liste d'un utilisateur déjà existant, puis l'état avec une propriété isAuthenticated:

 case 'AUTHENTICATE_USER':
        var users = state.userslist;
        var payloadUser = action.payload;
        for (let i = 0; i < users.length; i++) {
            let user = users[i]
            if (user.name === payloadUser.name) {
                return {...state, isAuthenticated: true };
            }
        };
        return {...state, isAuthenticated: false };

Maintenant dans Angular, j'attendrais juste que cet appel se termine et vérifie si cette valeur est true ou false, et accède à la page d'accueil en utilisant angular-router.

Mais comment pourrais-je obtenir la même chose dans react. J'utilise react-router Dans mon exemple d'application.

J'ai essayé de vérifier isAuthenticated dans ma fonction submitHandler juste en dessous de l'endroit où j'appelle this.props.authenticateUser(user), mais le problème est que this.props.isAuthenticateUser N'est pas mis à jour et renvoie false, que j'ai défini comme initialState dans mon réducteur.

Veuillez me dire comment je peux vérifier isAuthenticated après l'appel de la fonction authenticateUser afin de pouvoir poursuivre le routage de ma page d'accueil. Dois-je utiliser un promise et attendre que l'état soit mis à jour par redux puis le vérifier à nouveau ?? (Je sais que réagir est un chemin à sens unique et cela ne fonctionne pas de cette façon.)

De plus, si mon authentification échoue, comment afficher un panneau d'erreur sous mon formulaire de connexion. Je pense qu'en utilisant un composant pour le panneau d'erreur qui prend isAuthenticated en entrée et en vérifiant s'il est faux afin d'afficher (c'est-à-dire. NgShow like dans Angular.) Mais je suis peur que cela ne fonctionne pas aussi bien, car mon état ne sera pas mis à jour juste à temps.

Je sais que la fonction de rendu sera appelée avec tout changement d'état. Mais je ne peux tout simplement pas envelopper ma tête React clairement.

Edit : Par souci de concision, je n'ai pas fourni les créateurs d'action et le réducteur complet ci-dessus, mais plutôt montré uniquement l'opération de casse de commutateur pour authentifier l'utilisateur. Mon application suit l'architecture redux d'origine avec des actions, des réducteurs, des conteneurs, des composants et autres.

EDIT: Lien Github ici

10
v1shnu

Je vais essayer d'expliquer brièvement comment fonctionne le flux de données dans une application Redux:

  1. Le réducteur ne doit pas être appelé directement depuis le composant. Votre appel à authentifier l'utilisateur doit se trouver dans une action et c'est ce qui doit être distribué depuis le composant.

  2. Lorsque vous définissez l'action, vous pouvez attribuer une propriété pour définir le type d'action dont il s'agit. Par exemple, dans ce cas, il pourrait s'agir de type: AUTHENTICATE_USER

  3. Après la fin de l'action, le magasin redux appelle le réducteur où avec l'état actuel et l'action. Ici, l'état redux peut être mis à jour en fonction de action.type (Le deuxième extrait de code ci-dessus)

  4. C'est la partie la plus importante: votre composant doit avoir une méthode mapStateToProps qui transmet les valeurs de votre état Redux comme accessoires dans votre composant . Ainsi, à mesure que l'état change, les accessoires sont mis à jour et le composant s'affiche à nouveau. Pour utiliser mapStateToProps, vous devez implémenter connect depuis la bibliothèque react-redux. ( https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options )

Pour réaliser ce que vous voulez, voici ce que je propose:

  1. Dans la méthode componentWillReceiveProps de votre composant, recherchez props.isAuthenticated Et utilisez context.router.Push() pour naviguer si l'utilisateur est authentifié.

  2. Avoir également une vérification basée sur props.isAuthenticated Dans la méthode render du composant pour afficher le message d'erreur.

Quelques liens qui pourraient être utiles:

http://redux.js.org/docs/basics/DataFlow.html

http://redux.js.org/docs/basics/UsageWithReact.html

15
Nupur