91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React-router?v6怎么實現登錄驗證

發布時間:2022-05-30 09:40:23 來源:億速云 閱讀:513 作者:iii 欄目:開發技術

這篇文章主要講解了“React-router v6怎么實現登錄驗證”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“React-router v6怎么實現登錄驗證”吧!

此示例演示了一個包含三個頁面的簡單登錄流程:公共頁面、受保護頁面和登錄頁面。 為了查看受保護的頁面,你必須先登錄。
首先,訪問公共頁面。 然后,訪問受保護的頁面。 你尚未登錄,因此你將被重定向到登錄頁面。 登錄后,你將被重定向回受保護的頁面。

封裝 Context 包裹容器

首先封裝AuthProvider組件,利用Context特性共享那些對于一個組件樹而言是“全局”的數據。
全局定義usersignInsignOut數據和方法,signInsignOut使用了高階函數,也方便后續擴展和修改。

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 父級容器

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;

開發 Login 模塊

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;

開發 Protected 包裹容器

主要就是對登錄狀態進行校驗,成功則渲染子組件,否則跳轉回登錄頁面

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;

App 入口文件

入口文件沒有對路由進行懶加載優化,因為是小應用,所以實際開發還是要考慮性能優化的。

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怎么實現登錄驗證”的內容了,經過本文的學習后,相信大家對React-router v6怎么實現登錄驗證這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万年县| 桦南县| 湖北省| 庆安县| 泰来县| 定远县| 星座| 东莞市| 阳信县| 社会| 龙口市| 黔南| 余干县| 巴塘县| 柘荣县| 达日县| 河曲县| 铜陵市| 广宁县| 甘谷县| 特克斯县| 辽宁省| 莒南县| 阳西县| 东乡| 北辰区| 平阳县| 镇赉县| 巢湖市| 壶关县| 仁布县| 贵州省| 缙云县| 馆陶县| 简阳市| 阿合奇县| 堆龙德庆县| 工布江达县| 揭西县| 峨眉山市| 龙南县|