Первоначально контекст аутентификации React равен нулю - PullRequest
2 голосов
/ 29 мая 2020

Я использую контексты React, чтобы сохранить состояние аутентификации для моего приложения. В настоящее время у меня возникает проблема, когда всякий раз, когда я пытаюсь нажать /groups/:id, он всегда перенаправляет меня сначала на /login, а затем на /UserDash. Это происходит потому, что контекст моего AuthProvider обновляется недостаточно быстро, а мой частный маршрут использовал AuthContext, чтобы решить, перенаправлять или нет.

<AuthProvider>
    <Router>
        <Switch>
            <LoggedRoute exact path = "/" component = {Home}/>
            <Route exact path = "/login" component = {Login}/>
            <PrivateRoute exact path = "/groups/:id" component = {GroupDash}/>
            <PrivateRoute exact path = "/UserDash" component = {UserDash}/>
        </Switch>
    </Router>
</AuthProvider>

В другом файле:

export const AuthContext = React.createContext();

export const AuthProvider = ({children}) => {
  const [currentUser, setCurrentUser] = useState(null);
  useEffect(() => {
      firebaseApp.auth().onAuthStateChanged(setCurrentUser);
  },[]);
    return (
        <AuthContext.Provider
            value = {{currentUser}}
        >
            {children}
        </AuthContext.Provider>
    );

Мой частный маршрут:

const PrivateRoute = ({component: RouteComponent, ...rest}) => {
    const {currentUser} = useContext((context) => AuthContext);
    return (
        <Route
            {...rest}
            render={routeProps => (currentUser) ? (<RouteComponent{...routeProps}/>) : (<Redirect to={"/login"}/>)}
        />
    )
};

И моя страница входа

 const {currentUser} = useContext(AuthContext);
    if (currentUser) {
        return <Redirect to = "/UserDash" />
    }
    return (
        <button onClick={(e) => {googleLogin(history)}}>Log In</button>
    );

Есть ли там любой способ заставить контекст загружаться до того, как частный маршрут перенаправит пользователя на страницу входа? Вместо этого я пробовал использовать firebase.auth (). CurrentUser внутри моего PrivateRoute, но это тоже не удается, и меня все равно перенаправляют на "/login", а затем на "/UserDash".

1 Ответ

1 голос
/ 29 мая 2020

Поскольку useEffect запускается после рендеринга, а значение, получаемое в useEffect, берется из вызова asyn c, что может сделать, так это поддерживать состояние загрузки до тех пор, пока не будут доступны данные, например

export const AuthContext = React.createContext();

export const AuthProvider = ({children}) => {
  const [currentUser, setCurrentUser] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  useEffect(() => {
      firebaseApp.auth().onAuthStateChanged((user) => {
          setCurrentUser(); setIsLoading(false)
      });
  },[]);
    return (
        <AuthContext.Provider
            value = {{currentUser, isLoading}}
        >
            {children}
        </AuthContext.Provider>
    );
  }

Потом в приват Маршрут

const PrivateRoute = ({component: RouteComponent, ...rest}) => {
    const {currentUser, isLoading} = useContext((context) => AuthContext);
    if(isLoading) return <div>Loading...</div>
    return (
        <Route
            {...rest}
            render={routeProps => (currentUser) ? (<RouteComponent{...routeProps}/>) : (<Redirect to={"/login"}/>)}
        />
    )
};
...