Rumah  >  Soal Jawab  >  teks badan

Panduan untuk mencipta laluan yang dilindungi: Melaksanakan penghalaan yang dilindungi menggunakan react-router-dom

<p>Cara menggunakan <code>react-router-dom</code> untuk mencipta laluan yang dilindungi dan menyimpan respons dalam localStorage supaya pengguna boleh melihat butiran mereka semula pada kali seterusnya mereka membukanya. Selepas log masuk, mereka harus diubah hala ke halaman papan pemuka. </p> <p>Semua fungsi ditambah dalam ContextApi. </p> <p>Pautan kotak kod: Kod</p> <p>Saya cuba tetapi tidak berjaya.</p> <p>路由页面</p> <pre class="brush:php;toolbar:false;">import React, { useContext } daripada "react"; import { globalC } daripada "./context"; import { Route, Switch, BrowserRouter } daripada "react-router-dom"; import Perihal daripada "./Perihal"; import Papan Pemuka daripada "./Papan Pemuka"; import Log Masuk daripada "./Login"; import PageNotFound daripada "./PageNotFound"; fungsi Laluan() { const { authLogin } = useContext(globalC); console.log("authLogin", authLogin); kembali ( <Penghala Penyemak Imbas> <Tukar> {authLogin ? ( <> <Route path="/dashboard" component={Dashboard} tepat /> <Route exact path="/About" component={About} /> </> ) : ( <Route path="/" component={Login} tepat /> )} <Komponen laluan={PageNotFound} /> </Tukar> </BrowserRouter> ); } eksport Laluan lalai;</pre> <p>上下文页面</p> <pre class="brush:php;toolbar:false;">import React, { Component, createContext } daripada "react"; import axios daripada "axios"; eksport const globalC = createContext(); kelas eksport Gprov memanjangkan Komponen { negeri = { authLogin: null, authLoginerror: null }; componentDidMount() { var localData = JSON.parse(localStorage.getItem("loginDetail")); if (localData) { this.setState({ authLogin: localData }); } } loginData = tak segerak () => { biarkan muatan = { token: "ctz43XoULrgv_0p1pvq7tA", data: { nama: "nama pertama", e-mel: "internetEmail", telefon: "phoneHome", _ulang: 300 } }; tunggu aksios .post(`https://app.fakejson.com/q`, muatan) .then((res) => { jika (res.status === 200) { this.setState({ authLogin: res.data }); localStorage.setItem("loginDetail", JSON.stringify(res.data)); } }) .catch((err) => this.setState({ authLoginerror: err }) ); }; render() { // console.log(localStorage.getItem("loginDetail")); kembali ( <globalC.Pembekal nilai={{ ... negeri ini, loginData: this.loginData }} > {this.props.children} </globalC.Provider> ); } }</pre> <p><br /></p>
P粉011684326P粉011684326446 hari yang lalu498

membalas semua(2)saya akan balas

  • P粉968008175

    P粉9680081752023-08-24 09:21:05

    Untuk v6:

    import { Routes, Route, Navigate } from "react-router-dom";
    
    function App() {
      return (
        <Routes>
          <Route path="/public" element={<PublicPage />} />
          <Route
            path="/protected"
            element={
              <RequireAuth redirectTo="/login">
                <ProtectedPage />
              </RequireAuth>
            }
          />
        </Routes>
      );
    }
    
    function RequireAuth({ children, redirectTo }) {
      let isAuthenticated = getAuth();
      return isAuthenticated ? children : <Navigate to={redirectTo} />;
    }

    Pautan ke dokumentasi: https://gist.github.com/mjackson/d54b40a094277b7afdd6b81f51a0393f

    balas
    0
  • P粉562845941

    P粉5628459412023-08-24 09:02:03

    Soalan

    <BrowserRouter>
      <Switch>
        {authLogin ? (
          <>
            <Route path="/dashboard" component={Dashboard} exact />
            <Route exact path="/About" component={About} />
          </>
        ) : (
          <Route path="/" component={Login} exact />
        )}
    
        <Route component={PageNotFound} />
      </Switch>
    </BrowserRouter>

    Switch除了RouteRedirectTidak mengendalikan sebarang pemaparan lain di luar komponen. Jika anda ingin "bersarang" seperti ini, maka anda perlu membungkus setiap komponen dalam laluan generik, tetapi ini sama sekali tidak perlu.

    Komponen log masuk anda juga tidak mengendalikan ubah hala kembali ke "rumah" atau laluan peribadi lawatan asal.

    Penyelesaian

    react-router-dom v6

    Dalam versi 6, komponen penghalaan tersuai tidak lagi popular, kaedah pilihan adalah menggunakan komponen reka letak auth.

    import { Navigate, Outlet } from 'react-router-dom';
    
    const PrivateRoutes = () => {
      const location = useLocation();
      const { authLogin } = useContext(globalC);
    
      if (authLogin === undefined) {
        return null; // 或者加载指示器/旋转器等
      }
    
      return authLogin 
        ? <Outlet />
        : <Navigate to="/login" replace state={{ from: location }} />;
    }

    ...

    <BrowserRouter>
      <Routes>
        <Route path="/" element={<PrivateRoutes />} >
          <Route path="dashboard" element={<Dashboard />} />
          <Route path="about" element={<About />} />
        </Route>
        <Route path="/login" element={<Login />} />
        <Route path="*" element={<PageNotFound />} />
      </Routes>
    </BrowserRouter>

    atau

    const routes = [
      {
        path: "/",
        element: <PrivateRoutes />,
        children: [
          {
            path: "dashboard",
            element: <Dashboard />,
          },
          {
            path: "about",
            element: <About />
          },
        ],
      },
      {
        path: "/login",
        element: <Login />,
      },
      {
        path: "*",
        element: <PageNotFound />
      },
    ];

    ...

    export default function Login() {
      const location = useLocation();
      const navigate = useNavigate();
      const { authLogin, loginData } = useContext(globalC);
    
      useEffect(() => {
        if (authLogin) {
          const { from } = location.state || { from: { pathname: "/" } };
          navigate(from, { replace: true });
        }
      }, [authLogin, location, navigate]);
    
      return (
        <div
          style={{ height: "100vh" }}
          className="d-flex justify-content-center align-items-center"
        >
          <button type="button" onClick={loginData} className="btn btn-primary">
            登录
          </button>
        </div>
      );
    }

    react-router-dom v5

    Buat komponen PrivateRoute yang menggunakan konteks pengesahan anda.

    const PrivateRoute = (props) => {
      const location = useLocation();
      const { authLogin } = useContext(globalC);
    
      if (authLogin === undefined) {
        return null; // 或者加载指示器/旋转器等
      }
    
      return authLogin ? (
        <Route {...props} />
      ) : (
        <Redirect
          to={{
            pathname: "/login",
            state: { from: location }
          }}
        />
      );
    };

    Kemas kini komponen Login anda untuk mengendalikan pengalihan semula ke lawatan asal.

    export default function Login() {
      const location = useLocation();
      const history = useHistory();
      const { authLogin, loginData } = useContext(globalC);
    
      useEffect(() => {
        if (authLogin) {
          const { from } = location.state || { from: { pathname: "/" } };
          history.replace(from);
        }
      }, [authLogin, history, location]);
    
      return (
        <div
          style={{ height: "100vh" }}
          className="d-flex justify-content-center align-items-center"
        >
          <button type="button" onClick={loginData} className="btn btn-primary">
            登录
          </button>
        </div>
      );
    }

    Menjadikan semua laluan sebagai "senarai rata"

    function Routes() {
      return (
        <BrowserRouter>
          <Switch>
            <PrivateRoute path="/dashboard" component={Dashboard} />
            <PrivateRoute path="/About" component={About} />
            <Route path="/login" component={Login} />
            <Route component={PageNotFound} />
          </Switch>
        </BrowserRouter>
      );
    }

    balas
    0
  • Batalbalas