isAuthenticated
- это асинхронная c функция, поэтому вам придется дождаться результата, прежде чем ее можно будет использовать. Но это сложнее, чем это. Ваша PublicRoute
функция является компонентом , и компоненты должны синхронно возвращать контент, который вы хотите визуализировать (по крайней мере, пока мы не получим приостановку). Поскольку isAuthenticated
является асинхронным c, это означает, что вы должны визуализировать дважды: один раз, когда определяется результат isAuthenticated
, затем снова после. Самый простой способ сделать это - использовать состояние:
import { useEffect, useState } from 'react';
function PublicRoute( { component: Component, ...rest } ) {
const { authTokens } = useAuth();
const [isAuthenticated, setIsAuthenticated] = useState(null);
useEffect(() => {
isAuthenticated(authTokens).then(setIsAuthenticated);
async function isAuthenticated(token) {
if ( token === undefined ) return false;
try {
const response = await api.post( '/cT', { token } );
return response.status === 200;
} catch ( error ) {
console.log( 'Retorned false with error.' );
console.log( error );
return false;
};
}
}, [authTokens]);
console.log( 'Is authenticated?' );
console.log( isAuthenticated ); // Will be null (unknown), true, or false
if (isAuthenticated === null) {
// Render nothing for now; component will re-render after auth check
return null;
}
return (
<Route { ...rest }
render={
( props ) => ( isAuthenticated ) ?
( <Redirect to='/profile' /> ) :
( <Component { ...props } /> )
}
/>
);
}
Теперь ваш компонент возвращает контент, который React может обрабатывать вместо Promise, и обрабатывает асинхронность посредством повторных рендерингов. Ваш следующий фокус должен быть "что пользователи должны видеть, пока они ждут?" Подход, который требуется, заключается в том, чтобы вернуть null
, чтобы маршрут не отображался, но вы можете рассмотреть возможность рендеринга счетчиков, для которых может потребоваться перемещение этой функции проверки подлинности куда-нибудь еще в дереве компонентов.