Компонент React private route отображает дважды

#javascript #reactjs #firebase-authentication #react-router

#javascript #reactjs #firebase-аутентификация #реагирующий маршрутизатор

Вопрос:

Я пишу приложение React / firebase и пытаюсь заставить работать некоторые частные маршруты. Я использую {useAuthState} from react-firebase-hooks/auth , чтобы помочь мне пройти аутентификацию.

Приложение:

 let App = () => {
  const [user] = useAuthState(auth);
  return (
   <Navbar
      ...
      <a href="/user" />user</a>
      ...
   />
   <Router>
       <div className='main-content'>
       <Route path='/auth/signin' component={Login} />
       <ProtectedRoute path='/user' component={UserHome} 
        isAuth={user} />
   ..
  };

  

Защищенный маршрут:

 const ProtectedRoute = ({ component: Component, isAuth, ...rest }) => {
  return (
    <Route
      {...rest}
      render={(props) =>
        isAuth ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{ pathname: "/user/signin", state: { from: props.location } }}
          />
        )
      }
    />
  );
};

export default ProtectedRoute;
  

Но react продолжает визуализировать компоненты дважды, и при первом рендеринге реквизит равен null, что вызывает перенаправление защищенного маршрута.
Но при втором рендеринге все реквизиты есть, но потом уже поздно, и произошло перенаправление.

Можно ли дождаться загрузки всех реквизитов перед рендерингом или перенаправлением? Или есть какой-либо другой способ решить эту проблему?

С наилучшими пожеланиями

Комментарии:

1. насколько я могу судить, компонент отображает без реквизитов из-за асинхронного поведения js, поэтому до тех пор, пока firebase не вернет что-то, объекты инициализируются нулевыми значениями, и как только firebase извлекает информацию, она передается компоненту. попробуйте справиться с этой ситуацией со значением по умолчанию, отличным от null, возможно, false в качестве начального значения и добавьте условие isAuth!=null amp;amp; isAuth … или, может быть, попробуйте использовать async await в функции, которая устанавливает isAuth

Ответ №1:

Поскольку useAuthState для получения информации о пользователе может потребоваться некоторое время, вы должны использовать loading prop, который он предоставляет, чтобы дождаться его завершения:

 let App = () => {
  const [user, loading, error] = useAuthState(auth);
  if (loading) {
    return (
      <div>
        <p>Initialising User...</p>
      </div>
    );
  }
  if (error) {
    return (
      <div>
        <p>Error: {error}</p>
      </div>
    );
  }
  return (
    <Navbar
      ...
      <a href="/user" />user</a>
      ...
    />
    <Router>
       <div className='main-content'>
       <Route path='/auth/signin' component={Login} />
       <ProtectedRoute path='/user' component={UserHome} 
        isAuth={user} />
    ..
  };
  

Вы можете прочитать больше здесь