您好,登錄后才能下訂單哦!
這篇文章主要講解了“React-router v6怎么實現登錄驗證”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“React-router v6怎么實現登錄驗證”吧!
此示例演示了一個包含三個頁面的簡單登錄流程:公共頁面、受保護頁面和登錄頁面。 為了查看受保護的頁面,你必須先登錄。
首先,訪問公共頁面。 然后,訪問受保護的頁面。 你尚未登錄,因此你將被重定向到登錄頁面。 登錄后,你將被重定向回受保護的頁面。
首先封裝AuthProvider
組件,利用Context
特性共享那些對于一個組件樹而言是“全局”的數據。
全局定義user
、signIn
、signOut
數據和方法,signIn
、signOut
使用了高階函數,也方便后續擴展和修改。
Context
主要應用場景在于很多不同層級的組件需要訪問同樣一些的數據。請謹慎使用,因為這會使得組件的復用性變差。
如果你只是想避免層層傳遞一些屬性,組件組合(component composition)有時候是一個比Context
更好的解決方案。
import { ReactNode, createContext, useState } from "react"; export interface AuthContextType { user: any; signIn: (user: string, callback: VoidFunction) => void; signOut: (callback: VoidFunction) => void; } export let AuthContext = createContext<AuthContextType | null>(null); const fakeAuthProvider = { isAuthenticated: false, signIn(callback: VoidFunction) { this.isAuthenticated = true; setTimeout(callback, 100); }, signOut(callback: VoidFunction) { this.isAuthenticated = false; setTimeout(callback, 100); }, }; const AuthProvider = ({ children }: { children: ReactNode }) => { const [user, setUser] = useState<any>(null); let signIn = (newUser: string, callback: VoidFunction) => { return fakeAuthProvider.signIn(() => { setUser(newUser); callback(); }); }; let signOut = (callback: VoidFunction) => { return fakeAuthProvider.signOut(() => { setUser(null); callback(); }); }; return ( <AuthContext.Provider value={{ user, signIn, signOut }}> {children} </AuthContext.Provider> ); }; export default AuthProvider;
Layout
組件主要是針對登錄狀態進行校驗,然后做相應處理。利用react-router
v6中<Outlet />
組件顯示嵌套路由,相比于v5版本v6實現嵌套路由更加方便,省略了很多冗余的判斷代碼。
import { useContext } from "react"; import { useNavigate, Link, Outlet } from "react-router-dom"; import { AuthContext, AuthContextType } from "../AuthProvider"; const useAuth = () => useContext(AuthContext); const AuthStatus = () => { let auth = useAuth(); let { user, signOut } = auth as AuthContextType; let navigate = useNavigate(); if (!user) return <p>沒有登錄</p>; return ( <> <p>你好 {user}! </p> <button onClick={() => signOut(() => navigate("/"))}>退出</button> </> ); }; const Layout = () => { return ( <div> <AuthStatus /> <ul> <li> <Link to="/">公共頁面</Link> </li> <li> <Link to="/protected">受保護頁面</Link> </li> </ul> <Outlet /> </div> ); }; export default Layout;
import { useContext, FormEvent } from "react"; import { useNavigate, useLocation, Location } from "react-router-dom"; import { AuthContext, AuthContextType } from "../AuthProvider"; interface State extends Omit<Location, "state"> { state: { from: { pathname: string; }; }; } const useAuth = () => useContext(AuthContext); const Login = () => { let auth = useAuth(); let { signIn } = auth as AuthContextType; const { state } = useLocation() as State; let from = state.from.pathname || "/"; let navigate = useNavigate(); const handleSubmit = (event: FormEvent<HTMLFormElement>) => { event.preventDefault(); let formData = new FormData(event.currentTarget); let username = formData.get("username") as string; signIn(username, () => navigate(from, { replace: true })); }; return ( <div> <p>您必須登錄才能查看該頁面 {from}</p> <form onSubmit={handleSubmit}> <label> 用戶名: <input name="username" type="text" /> </label> <button type="submit">登錄</button> </form> </div> ); }; export default Login;
主要就是對登錄狀態進行校驗,成功則渲染子組件,否則跳轉回登錄頁面
import { useContext } from "react"; import { useLocation, Navigate } from "react-router-dom"; import { AuthContext, AuthContextType } from "../AuthProvider"; const useAuth = () => useContext(AuthContext); const RequireAuth = ({ children }: { children: JSX.Element }) => { let auth = useAuth(); let { user } = auth as AuthContextType; let location = useLocation(); if (!user) return <Navigate to="/login" state={{ from: location }} replace />; return children; }; export default RequireAuth;
入口文件沒有對路由進行懶加載優化,因為是小應用,所以實際開發還是要考慮性能優化的。
import { Routes, Route } from "react-router-dom"; import AuthProvider from "src/views/AuthProvider"; import Layout from "src/views/auth/layout"; import LoginPage from "src/views/auth/login"; import PublicPage from "src/views/auth/publicPage"; import RequireAuth from "src/views/auth/requireAuth"; import ProtectedPage from "src/views/auth/protectedPage"; const App = () => { return ( <AuthProvider> <Routes> <Route element={<Layout />}> <Route path="/" element={<PublicPage />} /> <Route path="/login" element={<LoginPage />} /> <Route path="/protected" element={ <RequireAuth> <ProtectedPage /> </RequireAuth> } /> </Route> </Routes> </AuthProvider> ); }; export default App;
感謝各位的閱讀,以上就是“React-router v6怎么實現登錄驗證”的內容了,經過本文的學習后,相信大家對React-router v6怎么實現登錄驗證這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。