首页 > 解决方案 > 如何将 Firebase onAuthStateChange 与新的 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 ContextanduseContext(FirebaseContext)来访问Firebase. 有没有办法使用新的hooks来模仿我创造的这个?withAuthentication HOCcomponents

我正在使用本教程

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

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

谢谢!

标签: reactjsfirebasefirebase-authenticationreact-hooks

解决方案


您可以编写一个Custom Hook注册效果并返回身份验证状态的

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> 
); 

推荐阅读