这篇文章主要讲解了“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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。