簡體   English   中英

React-Router-Dom 改變頁面狀態

[英]React-Router-Dom changing states of the page

大家好,我有一個問題。 當我輸入“儀表板”這是一條私人路線時,它首先將我重定向到“登錄”然后到儀表板。 True 和 False 一起玩。 我該如何解決它以不將我重定向到登錄然后到儀表板。

視頻示例: https://cdn.aboutluc.xyz/images/rc64kb6af92sswn3r4mv.mp4

代碼:

import React, {
  useState,
  useEffect
} from "react"

import { toast } from "react-toastify"

import {
  BrowserRouter as Router,
  Routes,
  Route,
  Navigate
} from "react-router-dom"

import {
  Login,
  Register,
  Dashboard,
} from "./Pages"

import {
  Navbar
} from "./Components"

import './App.css'
import "react-toastify/dist/ReactToastify.css"
import 'bootstrap/dist/css/bootstrap.min.css'

toast.configure()

const App = () => {

  const [ isAuthenticated, setIsAuthenticated ] = useState()

  const setAuth = (boolean) => {
    setIsAuthenticated(boolean)
  }

  const isAuth = async () => {
    try {
      const res = await fetch("http://localhost:5000/api/auth/verify", {
        headers: { JwtToken: localStorage.JwtToken }
      });

      const parseRes = await res.json();

      parseRes === true ? setIsAuthenticated(true) : setIsAuthenticated(false);
    } catch (error) {
      console.error(error)
    }
  }

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

  return (
    <>
      <Router>
        <Navbar setAuth={setAuth} isAuthenticated={isAuthenticated} />
        <Routes>

          <Route
            exact
            path="/login"
            element={
              isAuthenticated ? (
                <Navigate replace={true} to="/dashboard" />
              ) : (
                <Login setAuth={setAuth} />
              )
            }
          />

          <Route
            exact
            path="/register"
            element={
              isAuthenticated ? (
                <Navigate replace={true} to="/dashboard" />
              ) : (
                <Register setAuth={setAuth} />
              )
            }
          />

          <Route
            exact
            path="/dashboard"
            element={
              isAuthenticated ? (
                
                <Dashboard setAuth={setAuth} />
              ) : (
                <Navigate replace={true} to="/login" />
              )
            }
          />

        </Routes>
      </Router>
    </>
  )
}

export default App

我看到的可能問題是初始渲染上的“間隙”,其中isAuthenticated state 未定義, useEffect掛鈎回調設置 state 尚未運行。 如果您嘗試直接訪問受保護的路由,那么無論實際身份驗證狀態如何,代碼都會將您反彈到登錄路由。

為此,您通常希望使用“第三個”不確定因素 state 來“保留”重定向到身份驗證或允許訪問受保護組件,直到身份驗證狀態得到確認。

將身份驗證狀態抽象為身份驗證布局組件。

const AuthLayout = ({ isAuthenticated }) => {
  if (isAuthenticated === undefined) return null; // or loading spinner, etc...

  return isAuthenticated
    ? <Outlet />
    : <Navigate to="/login" replace />;
};

const AnonymousLayout = ({ isAuthenticated, to }) => {
  if (isAuthenticated === undefined) return null; // or loading spinner, etc...

  return isAuthenticated
    ? <Navigate to={to} replace />
    : <Outlet />;
};

使用布局來保護/保護特定路線。

<Routes>
  <Route
    element={(
      <AnonymousLayout isAuthenticated={isAuthenticated} to="/dashboard" />
    )}
  >
    <Route path="/login" element={<Login setAuth={setAuth} />} />
    <Route path="/register" element={<Register setAuth={setAuth} />} />
  </Route>
  <Route element={<AuthLayout isAuthenticated={isAuthenticated} />}>
    <Route path="/dashboard" element={<Dashboard setAuth={setAuth} />} />
  </Route>
</Routes>

注意:只有在App組件掛載時才調用isAuth 您可能想要調用此 function 或以其他方式驗證您的身份驗證令牌比這更頻繁。 isAuth傳遞給路由包裝器並在useEffect鈎子中調用可能不是一個糟糕的主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM