" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談React-router v6 實(shí)現(xiàn)登錄驗(yàn)證流程

 更新時(shí)間:2022年05月29日 09:40:53   作者:椒鹽味花生米  
本文主要介紹了React-router v6 實(shí)現(xiàn)登錄驗(yàn)證流程,主要介紹了公共頁(yè)面、受保護(hù)頁(yè)面和登錄頁(yè)面,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

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

封裝 Context 包裹容器

首先封裝AuthProvider組件,利用Context特性共享那些對(duì)于一個(gè)組件樹而言是“全局”的數(shù)據(jù)。
全局定義user、signIn、signOut數(shù)據(jù)和方法,signIn、signOut使用了高階函數(shù),也方便后續(xù)擴(kuò)展和修改。

Context主要應(yīng)用場(chǎng)景在于很多不同層級(jí)的組件需要訪問(wèn)同樣一些的數(shù)據(jù)。請(qǐng)謹(jǐn)慎使用,因?yàn)檫@會(huì)使得組件的復(fù)用性變差。
如果你只是想避免層層傳遞一些屬性,組件組合(component composition)有時(shí)候是一個(gè)比 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 父級(jí)容器

Layout組件主要是針對(duì)登錄狀態(tài)進(jìn)行校驗(yàn),然后做相應(yīng)處理。利用react-router v6中<Outlet />組件顯示嵌套路由,相比于v5版本v6實(shí)現(xiàn)嵌套路由更加方便,省略了很多冗余的判斷代碼。

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>沒(méi)有登錄</p>;
  return (
    <>
      <p>你好 {user}! </p>
      <button onClick={() => signOut(() => navigate("/"))}>退出</button>
    </>
  );
};

const Layout = () => {
  return (
    <div>
      <AuthStatus />
      <ul>
        <li>
          <Link to="/">公共頁(yè)面</Link>
        </li>
        <li>
          <Link to="/protected">受保護(hù)頁(yè)面</Link>
        </li>
      </ul>
      <Outlet />
    </div>
  );
};

export default Layout;

開發(fā) 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>您必須登錄才能查看該頁(yè)面 {from}</p>

      <form onSubmit={handleSubmit}>
        <label>
          用戶名: <input name="username" type="text" />
        </label>
        <button type="submit">登錄</button>
      </form>
    </div>
  );
};

export default Login;

開發(fā) Protected 包裹容器

主要就是對(duì)登錄狀態(tài)進(jìn)行校驗(yàn),成功則渲染子組件,否則跳轉(zhuǎn)回登錄頁(yè)面

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 入口文件

入口文件沒(méi)有對(duì)路由進(jìn)行懶加載優(yōu)化,因?yàn)槭切?yīng)用,所以實(shí)際開發(fā)還是要考慮性能優(yōu)化的。

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;

到此這篇關(guān)于淺談React-router v6 實(shí)現(xiàn)登錄驗(yàn)證流程的文章就介紹到這了,更多相關(guān)React-router登錄驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React中事件的類型定義方式

    React中事件的類型定義方式

    這篇文章主要介紹了React中事件的類型定義方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 解決React報(bào)錯(cuò)Unexpected default export of anonymous function

    解決React報(bào)錯(cuò)Unexpected default export of an

    這篇文章主要為大家介紹了React報(bào)錯(cuò)Unexpected default export of anonymous function解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React利用lazy+Suspense實(shí)現(xiàn)路由懶加載

    React利用lazy+Suspense實(shí)現(xiàn)路由懶加載

    這篇文章主要為大家詳細(xì)介紹了React如何利用lazy+Suspense實(shí)現(xiàn)路由懶加載,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-06-06
  • 詳解React中多種組件通信方式的實(shí)現(xiàn)

    詳解React中多種組件通信方式的實(shí)現(xiàn)

    在React中,組件之間的通信是一個(gè)非常重要的話題,React提供了幾種方式來(lái)實(shí)現(xiàn)跨組件通信,下面小編將詳細(xì)講講其中幾種通信方式,并提供實(shí)際的代碼示例,需要的可以參考下
    2023-11-11
  • React Native使用百度Echarts顯示圖表的示例代碼

    React Native使用百度Echarts顯示圖表的示例代碼

    本篇文章主要介紹了React Native使用百度Echarts顯示圖表的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • react使用css module無(wú)法重寫bootstrap樣式問(wèn)題及解決

    react使用css module無(wú)法重寫bootstrap樣式問(wèn)題及解決

    這篇文章主要介紹了react使用css module無(wú)法重寫bootstrap樣式問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • react?Scheduler?實(shí)現(xiàn)示例教程

    react?Scheduler?實(shí)現(xiàn)示例教程

    這篇文章主要為大家介紹了react?Scheduler?實(shí)現(xiàn)示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 從零開始搭建一個(gè)react項(xiàng)目開發(fā)

    從零開始搭建一個(gè)react項(xiàng)目開發(fā)

    這篇文章主要介紹了從零開始搭建一個(gè)react項(xiàng)目開發(fā),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • React中Portals與錯(cuò)誤邊界處理實(shí)現(xiàn)

    React中Portals與錯(cuò)誤邊界處理實(shí)現(xiàn)

    本文主要介紹了React中Portals與錯(cuò)誤邊界處理實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • 深入理解React中何時(shí)使用箭頭函數(shù)

    深入理解React中何時(shí)使用箭頭函數(shù)

    對(duì)于剛學(xué)前端的大家來(lái)說(shuō),對(duì)于React中的事件監(jiān)聽(tīng)寫法有所疑問(wèn)很正常,特別是React中箭頭函數(shù)使用這塊,下面這篇文章主要給大家深入的講解了關(guān)于React中何時(shí)使用箭頭函數(shù)的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08

最新評(píng)論

磴口县| 万盛区| 英超| 镇江市| 双辽市| 呼玛县| 阜新市| 新龙县| 高尔夫| 全椒县| 思南县| 深州市| 谷城县| 司法| 孝义市| 灌阳县| 革吉县| 依兰县| 上杭县| 册亨县| 台东市| 舟山市| 章丘市| 泰州市| 安泽县| 青海省| 鄂托克旗| 沁水县| 崇文区| 永靖县| 思南县| 焦作市| 江西省| 朔州市| 武汉市| 徐水县| 石渠县| 德安县| 南华县| 博客| 临桂县|