用React-Router-Dom V6配置私人路线

发布于 2025-02-13 09:13:37 字数 2462 浏览 0 评论 0原文

当访问者转到/(home)时,我希望他被重定向到/connexion“如果他没有连接。我为此创建了私人路线 ,我想实现用户是否连接的逻辑

import ProtectedRoutes from './middlewares/ProtectedRoutes';

return (
    <>
      <Routes>
        <Route path="/connexion" element={<Login />} />
        <Route path="/auto-connexion" element={<AutoConnect />} />

        <Route element={<AppLayout />} >
          <Route element={<ProtectedRoutes />}>
            <Route path="/" element={<Home />} />
            <Route path="/logical-entity-selection" element={<LogicalEntitySelection />} />
            <Route path="/produits" element={<Products />} />
            <Route path="/produits/:id" element={<Product />} />
            <Route path="/actualites" element={<Articles />} />
            <Route path="/actualites/id" element={<Article />} />
            <Route path="/mes-parametres" element={<MyAccount />} />
            <Route path="/mes-outils-et-services" element={<MyToolsAndServices />} />
            <Route path='*' element={<Login />} />
          </Route>
        </Route>
      </Routes>
    </>
  );

现在 preatectedRoutes.tsx

import { useEffect, useState } from "react"
import { Navigate, Outlet } from "react-router-dom"
import jwt_decode from "jwt-decode"
import instance from "../api/axios"

export default function ProtectedRoutes() {
    const [isLoggedIn, setIsLoggedIn] = useState(Boolean)

    const token = window.localStorage.getItem("token") || ''
    const decodedToken: any = jwt_decode(token)
    const uuid = decodedToken.uuid

    const isAuth = async () => {
        await instance.get(`/users/${uuid}`, {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        }).then((res) => {
            console.log(res)
            if (res.status === 200) setIsLoggedIn(true)
            return setIsLoggedIn(false)
        })
    }

    useEffect(() => {
        isAuth()
    }, [isLoggedIn])

    return isLoggedIn ? <Outlet /> : <Navigate to={'/connexion'} />
}

问题是,使用此代码,React渲染登录组件,因为它始终返回false,即使我有状态 新状态设置为true

200在我的请求之后,将 决定渲染<代码> home

我希望我不犹豫。

When the visitor goes to / (home), I want him to be redirected to /connexion" if he is not connected. I created Private routes for that, which works fine. Now, I want to implement the logic that will redirect the user according to if he is connected or not.

I have these routes in App.jsx:

import ProtectedRoutes from './middlewares/ProtectedRoutes';

return (
    <>
      <Routes>
        <Route path="/connexion" element={<Login />} />
        <Route path="/auto-connexion" element={<AutoConnect />} />

        <Route element={<AppLayout />} >
          <Route element={<ProtectedRoutes />}>
            <Route path="/" element={<Home />} />
            <Route path="/logical-entity-selection" element={<LogicalEntitySelection />} />
            <Route path="/produits" element={<Products />} />
            <Route path="/produits/:id" element={<Product />} />
            <Route path="/actualites" element={<Articles />} />
            <Route path="/actualites/id" element={<Article />} />
            <Route path="/mes-parametres" element={<MyAccount />} />
            <Route path="/mes-outils-et-services" element={<MyToolsAndServices />} />
            <Route path='*' element={<Login />} />
          </Route>
        </Route>
      </Routes>
    </>
  );

An this ProtectedRoutes.tsx :

import { useEffect, useState } from "react"
import { Navigate, Outlet } from "react-router-dom"
import jwt_decode from "jwt-decode"
import instance from "../api/axios"

export default function ProtectedRoutes() {
    const [isLoggedIn, setIsLoggedIn] = useState(Boolean)

    const token = window.localStorage.getItem("token") || ''
    const decodedToken: any = jwt_decode(token)
    const uuid = decodedToken.uuid

    const isAuth = async () => {
        await instance.get(`/users/${uuid}`, {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        }).then((res) => {
            console.log(res)
            if (res.status === 200) setIsLoggedIn(true)
            return setIsLoggedIn(false)
        })
    }

    useEffect(() => {
        isAuth()
    }, [isLoggedIn])

    return isLoggedIn ? <Outlet /> : <Navigate to={'/connexion'} />
}

The problem is that with this code, React render the Login Component because it returns always false, even if I have a status 200 after my request and set the new state to true.

How can I make my request FIRST, then set the new state for isLoggedIn, then decide to render Login component or Home component ?

I hope I made it clear. Don't hesitate to question me if not. Any help on this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

会发光的星星闪亮亮i 2025-02-20 09:13:37

除了必须使其正常工作之外,您还需要一个加载状态,我称其为isthecking。另外,您应该更改的代码下面的块,因为您将isloggedin设置为 true,然后在false之后。

 if (res.status === 200) setIsLoggedIn(true)
 return setIsLoggedIn(false)

解决方案:

import { useEffect, useState } from "react"
import { Navigate, Outlet } from "react-router-dom"
import jwt_decode from "jwt-decode"
import instance from "../api/axios"

export default function ProtectedRoutes() {
    const [isLoggedIn, setIsLoggedIn] = useState(false)
    const [isChecking, setIsChecking] = useState(true)
    const token = window.localStorage.getItem("token") || ''
    const decodedToken: any = jwt_decode(token)
    const uuid = decodedToken.uuid

    const isAuth = async () => {
        await instance.get(`/users/${uuid}`, {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        }).then((res) => {
            console.log(res)
            if (res.status === 200) setIsLoggedIn(true)
            setIsChecking(false);
            return;
        })
    }

    useEffect(() => {
        isAuth()
    }, [isLoggedIn])

    if(isChecking) return <p>Checking....</p>

    return isLoggedIn ? <Outlet /> : <Navigate to={'/connexion'} />
}

You would need a loading state in addition to what you have to make it work correctly, I called it isChecking. Also the below block of code that you have should be changed, because you are setting isLoggedIn to true and right after to false.

 if (res.status === 200) setIsLoggedIn(true)
 return setIsLoggedIn(false)

Solution:

import { useEffect, useState } from "react"
import { Navigate, Outlet } from "react-router-dom"
import jwt_decode from "jwt-decode"
import instance from "../api/axios"

export default function ProtectedRoutes() {
    const [isLoggedIn, setIsLoggedIn] = useState(false)
    const [isChecking, setIsChecking] = useState(true)
    const token = window.localStorage.getItem("token") || ''
    const decodedToken: any = jwt_decode(token)
    const uuid = decodedToken.uuid

    const isAuth = async () => {
        await instance.get(`/users/${uuid}`, {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        }).then((res) => {
            console.log(res)
            if (res.status === 200) setIsLoggedIn(true)
            setIsChecking(false);
            return;
        })
    }

    useEffect(() => {
        isAuth()
    }, [isLoggedIn])

    if(isChecking) return <p>Checking....</p>

    return isLoggedIn ? <Outlet /> : <Navigate to={'/connexion'} />
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文