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

How do I use the Firebase onAuthStateChange with the new 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 的需求。我已经通过使用 React ContextuseContext(FirebaseContext) 访问 Firebase 的单个实例来删除 withFirebase() HOC。有没有办法使用新的 hooks 在我创建的 components 中模仿这个 withAuthentication HOC

我正在使用这个教程

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

标题为 "Session Handling with Higher-Order Components" 的部分包含此部分。

谢谢!

你可以写一个Custom Hook注册一个效果和returns授权状态

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