web-dev-qa-db-fra.com

Gérer correctement la déconnexion avec React Native

J'ai une application native React qui affiche les différents navigateurs selon qu'il existe ou non un utilisateur Firebase authentifié.

Voici ma principale classe d'application:

export default class App extends Component {
  state = { loggedIn: null }

  componentWillMount() {
    firebase.initializeApp({...});

    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        this.setState({ loggedIn: true });
      } else {
        this.setState({ loggedIn: false });
      }
    });
  }

  renderContent() {
    switch (this.state.loggedIn) {
      case true:
        return (
          <MenuContext>
            <MainNavigator />
          </MenuContext>
        );
      case false:
        return (
          <AuthNavigator />
        );
      default:
        return (
          <View style={styles.spinnerStyle}>
            <Spinner size="large" />
          </View>
        );
    }
  }

  render() {
    return (
      <Provider store={store}>
        {this.renderContent()}
      </Provider>
    );
  }
}

Maintenant, cela fonctionne parfaitement avec un nouveau rendu du navigateur approprié lorsqu'un utilisateur se connecte.

Le problème que j'ai est de me déconnecter. Dans mon MainNavigator (celui qui montre quand un utilisateur est connecté), j'ai un bouton de déconnexion qui déconnecte l'utilisateur. Implémenté comme ceci:

signOutUser = async () => {
    try {
        await firebase.auth().signOut();
    } catch (e) {
        console.log(e);
    }
}

render() {
    return (
        ...
        <Button title="logout" onPress={() => this.signOutUser()} />
    )
}

Cela fait ce qui est attendu, cependant, j'obtiens l'avertissement suivant que je veux résoudre:

Avertissement: ne peut mettre à jour qu'un composant monté ou monté. Cela signifie généralement que vous avez appelé setState, replaceState ou forceUpdate sur un composant non monté. C'est un no-op.

Quelle est la meilleure façon d'implémenter cette fonctionnalité de déconnexion?

Edit: J'utilise le react-navigation bibliothèque pour gérer la navigation de mon application.

6

Je pense que la génération de votre navigateur en fonction de l'état d'un composant de l'application peut être dangereuse et peut entraîner ce problème. Lors de la déconnexion, vous devez rediriger vers le composant en charge de l'enregistrement ou de la connexion et ne pas laisser l'État en charge de régénérer une partie d'une autre navigation.

Ce que vous pouvez faire est dans votre composant d'application, au lieu de retourner MainNavigator ou AuthNavigator, vous pouvez renvoyer à la fois Navigator et ajouter une route appelée Loading par exemple, qui affichera un écran de chargement et qui sera la route initiale en charge du routage de votre application en fonction sur l'utilisateur est connecté ou non.

Exemple de StackNavigator avec ce cas

const Navigator = StackNavigator({
  Main: {
    screen: MainComponent,
  },
  Auth: {
    screen: AuthComponent,
  },
  Loading: {
    screen: LoadingComponent
  },
},{
    initialRouteName : 'Loading'
});

dans votre LoadingComponent, vous rendrez votre spinner

render() {
  return(
    <View style={styles.spinnerStyle}>
      <Spinner size="large" />
    </View>
  );
}

Et dans componentDidMount of LoadingComponent:

firebase.auth().onAuthStateChanged(user => {
  if (user) {
      navigate('Home');
  } else {
      navigate('Login');
  }
});

Avec cela, l'écran de chargement s'affichera lorsque vous ouvrirez votre application, puis redirigerez vers la bonne page en fonction de l'utilisateur connecté ou non.

Et dans votre redirection signOutUser vers la page de connexion

signOutUser = async () => {
    try {
        await firebase.auth().signOut();
        navigate('Auth');
    } catch (e) {
        console.log(e);
    }
}
11
Gabriel Diez