Я защищаю свои маршруты с помощью <ProtectedRoutes/>
, сценарий заключается в том, чтобы после успешного входа в систему перейти к /dashboard
, проблема в том, что независимо от того, сколько раз я успешно входил в систему, URL-адрес браузера менялся на /dashboard
менее чем на секунду, а затем переходил снова вернемся на страницу /login
. Я получил объект, содержащий всю информацию об аутентифицированном пользователе, из супабазы.
вот мои маршруты, все маршруты я проложила в детстве до <ProtectedRoutes/>
:
const router = createBrowserRouter([
{
element: <ProtectedRoutes/>,
children: [
{
element: <AppLayouts />,
children: [
{
path: "/",
element: <Navigate to = "/dashboard" replace />,
},
{
path: "/dashboard",
element: <Dashboard />,
},
{
path: "/users",
element: <NewUsers />,
},
{
path: "/account",
element: <Account />,
},
{
path: "/bookings",
element: <Bookings />,
},
{
path: "/bookings/:id",
element: <OneBookingDetails/>,
},
{
path: "/checkin/:id",
element: <Checkin/>,
},
{
path: "/cabins",
element: <Cabins />,
},
{
path: "/settings",
element: <Settings />,
},
],
},
]
},
{
path: "/login",
element: <Login />,
},
{
path: "*",
element: <PageNotFound />,
},
]);
Защищенные маршруты:
export default function ProtectedRoutes({children}) {
const navigate = useNavigate();
// 1) load the authenticated User:
const {isAuthenticated, isLoading} = useUser();
useEffect(function(){
// 3) not an authenticaed user? then redirect to the login page
if (!isAuthenticated && !isLoading) navigate("/login");
}, [isAuthenticated, isLoading, navigate]);
// 2) show a spinner while the process of checking is taking place:
if (isLoading) return <SpinnerContainer><Spinner/></SpinnerContainer>
// 4) an authenticated user? render the app (children):
if (isAuthenticated) return children;
}
использовать хук useUser:
import { useQuery } from "@tanstack/react-query";
import { getCurrentUser } from "../../services/apiAuth";
export async function useUser() {
const {isLoading, data: user, fetchStatus} = useQuery({
queryKey: ["user"],
queryFn: getCurrentUser
});
return {isLoading, fetchStatus, user, isAuthenticated: user?.role === "authenticated"};
}
хук useLogin, который отвечает за переход к /dashboard
(обратите внимание, что я получал toast.success("Welcome Back!");
после каждого процесса входа в систему:
import { useMutation } from "@tanstack/react-query";
import { login as loginApi } from "../../services/apiAuth";
import { useNavigate } from "react-router-dom";
import toast from "react-hot-toast";
export function useLogin() {
const navigate = useNavigate();
const {isLoading: isLogging, mutate: login} = useMutation({
mutationFn: ({email, password}) => loginApi({email, password}),
onSuccess: () => {
toast.success("Welcome Back!");
navigate("/dashboard");
},
onError: (error) => {
console.info(error.message);
toast.error("something went wrong, pleast try to login again.")
}
});
return {isLogging, login}
}
ОБНОВЛЯТЬ:
печать объекта user
внутри useEffect()
есть undefined
, но его нет внутри userUser()
когда я удалил это условие if (!isAuthenticated && !isLoading) navigate("/login");
, меня перенаправили на /dashboard
, но ничего не появилось, страница была белой, как и все остальные страницы.
Я нашел проблему, моя проблема заключалась в двух вещах:
первое: ключевое слово async
в крючке useUser
, теперь оно удалено
во-вторых: я изменил реализацию маршрутизаторов следующим образом:
const router = createBrowserRouter([
{
element: <ProtectedRoutes><AppLayouts/></ProtectedRoutes>,
children: [
{
path: "/",
element: <Navigate to = "/dashboard" replace />,
},
{
path: "/dashboard",
element: <Dashboard />,
},
{
path: "/users",
element: <NewUsers />,
},
{
path: "/account",
element: <Account />,
},
{
path: "/bookings",
element: <Bookings />,
},
{
path: "/bookings/:id",
element: <OneBookingDetails/>,
},
{
path: "/checkin/:id",
element: <Checkin/>,
},
{
path: "/cabins",
element: <Cabins />,
},
{
path: "/settings",
element: <Settings />,
}
]
},
{
path: "/login",
element: <Login />,
},
{
path: "*",
element: <PageNotFound />,
}]);
теперь все работает нормально.
Лучше всего было бы записать:
{isAuthenticated, isLoading}
иuser
(в хуке useUser). Также проверьте/поделитесь кодамиAppLayouts
иDashboard
. Возможно, они перенаправляют