如何将Firebase onAuthStateChange与新的React Hooks结合使用?

时间:2019-03-26 21:17:25

标签: reactjs firebase firebase-authentication react-hooks

我正在使用Firebase对应用程序的用户进行身份验证。我已经创建了SignInSignUp表单,并且可以成功创建新用户并使用存储的用户登录。但是,问题出在维护Reload之后用户保持登录状态。

我在教程中看到的完成方式是使用类似以下内容的HOC来检查当前用户是否已登录。

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;

不过,我希望使用新的React Hooks来消除对HOCs的需求。我已经通过使用withFirebase()HOC访问React Context的单个实例来删除useContext(FirebaseContext) Firebase。有没有办法使用新的hooks来模仿我在withAuthentication中创建的HOC components

我正在使用本教程

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

标题为“使用高阶组件的会话处理”的部分包含这一部分。

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以编写Custom Hook来注册效果并返回auth状态

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;

,并且在任何Component中,您都可以使用它

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

   return (...)
}

Index.jsx中将包含此代码

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

此Firebase Provider的定义如下,

import Firebase from './firebase';

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

答案 1 :(得分:0)

您好,Shubham Khatri提供的信息非常有帮助,并帮助我构建了自己的组件,但他使用Context来管理状态。如果您刚刚开始学习react和firebase,我会发现将状态包含在组件中比较容易(即使不正确)。

因此,对我而言,不使用Context的简单解决方案是仅使用react挂钩构建它,如下所示:

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;