web-dev-qa-db-fra.com

Comment utiliser Firebase onAuthStateChange avec les nouveaux React Hooks?

J'utilise Firebase pour authentifier les utilisateurs de mon application. J'ai créé les formulaires SignIn et SignUp et je peux créer avec succès de nouveaux utilisateurs et me connecter avec les utilisateurs stockés. Cependant, le problème vient du maintien de l'état de connexion de l'utilisateur après un Reload.

La façon dont je l'ai vu dans les didacticiels consiste à utiliser un HOC comme le suivant pour vérifier si l'utilisateur actuel est connecté.

const withAuthentication = Component => {
  class WithAuthentication extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        authUser: null,
      };
    }

    componentDidMount() {
      this.listener = this.props.firebase.auth.onAuthStateChanged(
        authUser => {
          authUser
            ? this.setState({ authUser })
            : this.setState({ authUser: null });
        },
      );
    }

    componentWillUnmount() {
      this.listener();
    }

    render() {
    return (
      <AuthUserContext.Provider value={this.state.authUser}>
        <Component {...this.props} />
      </AuthUserContext.Provider>
      );
    }
  }

  return withFirebase(WithAuthentication);
};

export default withAuthentication;

Cependant, je cherche à utiliser le nouveau ReactHooks pour supprimer le besoin de HOCs. J'ai déjà supprimé la withFirebase()HOC en utilisant les React Context Et useContext(FirebaseContext) pour accéder à une seule instance de Firebase. Existe-t-il un moyen d'utiliser le nouveau hooks pour imiter ce withAuthenticationHOC dans components que je crée?

J'utilise ce tutoriel

https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/

La section intitulée "Gestion des sessions avec des composants d'ordre supérieur" contient cette partie.

Merci!

11
Tristan Trainer

Vous pouvez écrire un Custom Hook qui enregistre un effet et renvoie l'état d'authentification

const useFirebaseAuthentication = (firebase) => {
    const [authUser, setAuthUser] = useState(null);

    useEffect(() =>{
       const unlisten = firebase.auth.onAuthStateChanged(
          authUser => {
            authUser
              ? setAuthUser(authUser)
              : setAuthUser(null);
          },
       );
       return () => {
           unlisten();
       }
    });

    return authUser
}

export default useFirebaseAuthentication;

et dans n'importe quel Component vous pouvez l'utiliser comme

const MyComponent = (props) => {
   const firebase = useContext(FirebaseContext);
   const authUser = useFirebaseAuthentication(firebase);

   return (...)
}

Index.jsx contiendra ce code

ReactDOM.render( 
   <FirebaseProvider> 
      <App /> 
   </FirebaseProvider>, 
   document.getElementById('root')); 

Ce fournisseur Firebase est défini comme ceci,

import Firebase from './firebase';

const FirebaseContext = createContext(); 
export const FirebaseProvider = (props) => ( 
   <FirebaseContext.Provider value={new Firebase()}> 
      {props.children} 
   </FirebaseContext.Provider> 
); 
11
Shubham Khatri

Salut les informations de Shubham Khatri ont été très utiles et m'ont aidé à créer mon propre composant mais il a utilisé Context pour gérer l'état. Si vous commencez juste à apprendre à réagir et à Firebase, j'ai trouvé plus facile (même si ce n'était pas le cas) d'avoir l'état dans mon composant.

Donc, la solution simple pour moi sans utiliser Context était de le construire avec des hooks réactifs uniquement comme ceci:

const useAuth = () => {
  const fireUser = firebase.auth().currentUser;
  const [user, setUser] = useState(fireUser);

  useEffect(() => {
    const unsub = firebase.auth().onAuthStateChanged((user) => {
      user ? setUser(user) : setUser(null);
    });
    return () => {
      unsub();
    };
  });
  return user;
};

const HomeV2 = () => {

  const user = useAuth();


  return (
    <div>
      <Link to="/">React Hooks </Link>
      <LogPage />
      {user ? <p>User is HERE</p> : <p>There's no user !</p>}
    </div>
  );
};

export default HomeV2;
0
Ili