#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} />
..
};
Вы можете прочитать больше здесь