<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
React Router v6是React應用程式的一個流行且功能強大的路由庫。它提供了一種宣告式的、基於元件的路由方法,並能處理URL引數、重定向和載入資料等常見任務。
這個最新版本的React Router引入了很多新概念,比如<Outlet />
和layout
佈局路由,但相關檔案仍然很少。
本文將演示如何使用React Router v6
建立受保護的路由以及如何新增身份驗證。
開啟終端,執行以下命令建立一個新的 React 專案:
> npx create-react-app ReactRouterAuthDemo > cd ReactRouterAuthDemo
接下來,在 React 應用程式中安裝 React Router
作為依賴項:
> npm install react-router-dom
一旦 React Router 依賴項安裝好,我們就可以開始編輯src/index.js
檔案。
首先,從 react-router-dom
中匯入 BrowserRouter
元件,然後用<BrowserRouter />
包裹 <App />
元件,就像這樣:
import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import { BrowserRouter } from "react-router-dom"; import App from "./App"; const rootElement = document.getElementById("root"); const root = createRoot(rootElement); root.render( <StrictMode> <BrowserRouter> <App /> </BrowserRouter> </StrictMode> );
React Router提供了 <Routes />
和 <Route />
元件,使我們能夠根據元件的當前位置來渲染它們。
import { Routes, Route } from "react-router-dom"; import { LoginPage } from "./pages/Login"; import { HomePage } from "./pages/Home"; import "./styles.css"; export default function App() { return ( <Routes> <Route path="/" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} /> </Routes> ); }
<Route />
提供了應用程式和 React 元件之間路徑的對映。例如,當用戶導航到/login
時,要渲染LoginPage
元件,我們只需要像這樣提供<Route />
:
<Route path="/login" element={<LoginPage />} />
<Route />
元件可以看作是一個 if
語句,只有當元素與指定的路徑匹配時,它才會作用於URL
的位置。
<Routes />
元件是 React Router v5
中的 <Switch />
元件的替代品。
我們可以通過建立Login.jsx
和Home.jsx
來使用 <Routes />
:
// Login.jsx export const LoginPage = () => ( <div> <h1>This is the Login Page</h1> </div> ); // Home.jsx export const HomePage = () => ( <div> <h1>This is the Home Page</h1> </div> );
接下來,我們將執行下面的命令來啟動應用程式:
> npm run start
在瀏覽器中,我們預設會看到Home
元件。如果我們使用/login
路由,我們將看到LoginPage
元件呈現在螢幕上。
或者,我們也可以使用一個普通的JavaScript物件,通過useRoutes
勾點來表示應用程式中的路由。這是一種定義路由的功能方法,其工作方式與< routes />
和<Route />
元件相同。
import { useRoutes } from "react-router-dom"; // ... export default function App() { const routes = useRoutes([ { path: "/", element: <HomePage /> }, { path: "/login", element: <LoginPage /> } ]); return routes; }
既然基本設定已經完成,讓我們看看如何建立受保護的路由,從而使未經身份驗證的使用者無法存取應用程式中的某些內容。
在建立受保護的路由之前,讓我們先建立一個自定義勾點,它將使用Context API
和useContext
勾點處理通過身份驗證的使用者的狀態。
import { createContext, useContext, useMemo } from "react"; import { useNavigate } from "react-router-dom"; import { useLocalStorage } from "./useLocalStorage"; const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [user, setUser] = useLocalStorage("user", null); const navigate = useNavigate(); // 驗證使用者許可權的時候,存取該函數 const login = async (data) => { setUser(data); navigate("/profile"); }; // 登出 const logout = () => { setUser(null); navigate("/", { replace: true }); }; const value = useMemo( () => ({ user, login, logout }), [user] ); return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>; }; export const useAuth = () => { return useContext(AuthContext); };
上述 useAuth
勾點中,我們暴露了使用者的狀態和一些用於使用者登入和登出的方法。當用戶登出時,我們使用 React Router
的 useNavigate
勾點將他們重定向到主頁。
為了在頁面重新整理時保持使用者的狀態,我們將使用 useLocalStorage
勾點,它將在瀏覽器的本地儲存中同步狀態值。
import { useState } from "react"; export const useLocalStorage = (keyName, defaultValue) => { const [storedValue, setStoredValue] = useState(() => { try { const value = window.localStorage.getItem(keyName); if (value) { return JSON.parse(value); } else { window.localStorage.setItem(keyName, JSON.stringify(defaultValue)); return defaultValue; } } catch (err) { return defaultValue; } }); const setValue = (newValue) => { try { window.localStorage.setItem(keyName, JSON.stringify(newValue)); } catch (err) {} setStoredValue(newValue); }; return [storedValue, setValue]; };
<ProtectedRoute />
元件將從 useAuth
勾點中檢查當前使用者的狀態,如果使用者沒有經過身份驗證,則重定向到/
路徑。
import { Navigate } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const ProtectedRoute = ({ children }) => { const { user } = useAuth(); if (!user) { // user is not authenticated return <Navigate to="/" />; } return children; };
要重定向使用者,我們使用 <Navigate />
元件。當父元件呈現當前位置時,<Navigate />
元件會改變當前位置。它在內部使用 usenavate
勾點。
在 App.js
檔案中,我們可以用 <ProtectedRoute />
元件包裝page
元件。例如下面,我們使用 <ProtectedRoute />
包裝<SettingsPage />
和 <ProfilePage />
元件。現在,當未經身份驗證的使用者試圖存取 /profile
或 /settings
路徑時,他們將被重定向到主頁。
import { Routes, Route } from "react-router-dom"; import { LoginPage } from "./pages/Login"; import { HomePage } from "./pages/Home"; import { SignUpPage } from "./pages/SignUp"; import { ProfilePage } from "./pages/Profile"; import { SettingsPage } from "./pages/Settings"; import { ProtectedRoute } from "./components/ProtectedRoute"; export default function App() { return ( <Routes> <Route path="/" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} /> <Route path="/register" element={<SignUpPage />} /> <Route path="/profile" element={ <ProtectedRoute> <ProfilePage /> </ProtectedRoute> } /> <Route path="/settings" element={ <ProtectedRoute> <SettingsPage /> </ProtectedRoute> } /> </Routes> ); }
如果受保護的路由數量有限,上面的方法工作得很好,但如果有多個這樣的路由,我們就必須把每個都包裝起來,這很繁瑣。
相反,我們可以使用React Router v6的巢狀路由特性,將所有受保護的路由封裝在一個佈局中。
React Router v6中最強大的特性之一是巢狀路由。這個特性允許我們有一個包含其他子路由的路由。我們的大多數佈局都與URL上的片段相耦合,React Router完全支援這一點。
例如,我們可以在<HomePage />
和 <LoginPage />
路由中新增一個父元件 <Route />
,就像這樣:
import { ProtectedLayout } from "./components/ProtectedLayout"; import { HomeLayout } from "./components/HomeLayout"; // ... export default function App() { return ( <Routes> <Route element={<HomeLayout />}> <Route path="/" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} /> </Route> <Route path="/dashboard" element={<ProtectedLayout />}> <Route path="profile" element={<ProfilePage />} /> <Route path="settings" element={<SettingsPage />} /> </Route> </Routes> ); }
父元件 <Route />
也可以有一個路徑,它負責在螢幕上呈現子元件<Route />
。
當用戶導航到 /dashboard/profile
時,路由器將呈現 <ProfilePage />
。為了實現這一點,父路由元素必須有一個 <Outlet />
元件來呈現子元素。Outlet
元件使巢狀的 UI 在呈現子路由時可見。
父路由元素還可以具有額外的公共業務邏輯和使用者介面。例如,在<ProtectedLayout />
元件中,我們已經包含了私有路由邏輯和一個通用導覽列,當子路由被呈現時,它將是可見的。
import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const ProtectedLayout = () => { const { user } = useAuth(); if (!user) { return <Navigate to="/" />; } return ( <div> <nav> <Link to="/settings">Settings</Link> <Link to="/profile">Profile</Link> </nav> <Outlet /> </div> ) };
除了<Outlet />
元件,我們還可以選擇使用 useOutlet
勾點,它的作用是一樣的:
import { Link, Navigate, useOutlet } from "react-router-dom"; // ... export const ProtectedLayout = () => { const { user } = useAuth(); const outlet = useOutlet(); if (!user) { return <Navigate to="/" />; } return ( <div> <nav> <Link to="/settings">Settings</Link> <Link to="/profile">Profile</Link> </nav> {outlet} </div> ); };
與受保護路由類似,我們不希望通過身份驗證的使用者存取 /login
路徑。讓我們在 <HomeLayout />
元件中處理它:
import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const HomeLayout = () => { const { user } = useAuth(); if (user) { return <Navigate to="/dashboard/profile" />; } return ( <div> <nav> <Link to="/">Home</Link> <Link to="/login">Login</Link> </nav> <Outlet /> </div> ) };
值得花一些時間來更好地理解 React Router v6 的工作原理,特別是使用者身份驗證。
與以前的版本相比,React Router v6是一個巨大的改進。它快速、穩定、可靠。除了更容易使用之外,它還有很多新特性,比如<Outlets />
和一個改進的<Route />
元件,這大大簡化了 React 應用中的路由。
我希望本指南對您有所幫助,希望您對如何使用React Router v6處理使用者身份驗證有了更好的理解。
到此這篇關於使用React Router v6 進行身份驗證完全指南的文章就介紹到這了,更多相關React Router v6驗證內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45