Création d'itinéraires protégés : un guide pratique utilisant React-Router-dom
P粉596191963
P粉596191963 2023-08-24 11:22:28
0
2
500
<p>Comment utiliser <code>react-router-dom</code> pour créer une route protégée et stocker la réponse dans localStorage afin que l'utilisateur puisse consulter à nouveau ses détails la prochaine fois qu'il l'ouvrira. Une fois connectés, ils doivent être redirigés vers la page du tableau de bord. </p> <p>Toutes les fonctions sont ajoutées dans ContextApi.Codesandbox链接:Code</p> <p>我尝试过,但无法实现</p> <p>路由页面</p> <pre class="brush:php;toolbar:false;">importer React, { useContext } depuis "react" ; importer { globalC } depuis "./context" ; importer {Route, Switch, BrowserRouter } depuis "react-router-dom" ; importer À propos de "./À propos" ; importer le tableau de bord depuis "./Dashboard" ; importer la connexion depuis "./Login" ; importer PageNotFound depuis "./PageNotFound" ; fonction Routes() { const { authLogin } = useContext(globalC); console.log("authLogin", authLogin); retour ( <NavigateurRouter> <Commutateur> {authConnexion ? ( ≪> <Route path="/dashboard" composant={Dashboard} exact /> <Route exact path="/À propos" composant={À propos} /> ≪/> ) : ( <Route path="/" composant={Connexion} exact /> )} <Composant d'itinéraire={PageNotFound} /> </Commutateur> </NavigateurRouter> ); } exporter les itinéraires par défaut ;</pre> <p>上下文页面</p> <pre class="brush:php;toolbar:false;">importer React, { Component, createContext } depuis "react" ; importer des axios depuis "axios" ; export const globalC = createContext(); la classe d'exportation Gprov étend le composant { état = { connexion auth : null, authLoginerror : null } ; composantDidMount() { var localData = JSON.parse(localStorage.getItem("loginDetail")); si (donnéeslocales) { this.setState({ connexion auth : localData }); } } loginData = async () => { laissez la charge utile = { jeton : "ctz43XoULrgv_0p1pvq7tA", données: { nom : "nomPremier", email : "internetEmail", téléphone : "téléphoneAccueil", _répétition : 300 } } ; attendre axios .post(`https://app.fakejson.com/q`, charge utile) .then((res) => { si (res.status === 200) { this.setState({ connexion auth : res.data }); localStorage.setItem("loginDetail", JSON.stringify(res.data)); } }) .catch((err) => this.setState({ authLoginerror : erreur }) ); } ; rendre() { // console.log(localStorage.getItem("loginDetail")); retour ( <globalC.Provider valeur={{ ...cet.état, données de connexion : this.loginData }} > {this.props.enfants} </globalC.Provider> ); } }≪/pré> <p><br /></p>
P粉596191963
P粉596191963

répondre à tous(2)
P粉253518620

Pour la 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} />;
}

Lien du document : https://gist.github.com/mjackson/d54b40a094277b7afdd6b81f51a0393f

P粉505917590

Question

<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除了RouteRedirectAucun autre rendu ne sera traité en dehors du composant. Si vous vouliez « imbriquer » comme ceci, vous devrez alors envelopper chaque composant dans une route générique, mais cela est totalement inutile.

Votre composant de connexion ne gère pas encore la redirection vers le « domicile » ou l'itinéraire privé d'origine visité.

Solution

react-router-domv6

Dans la version 6, les composants de routage personnalisés ne sont plus populaires, la méthode préférée consiste à utiliser des composants de mise en page d'authentification.

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>

ou

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-domv5

Créez un composant PrivateRoute qui consomme votre contexte d'authentification.

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 }
      }}
    />
  );
};

Mettez à jour votre composant Login pour gérer les redirections de routage vers la visite d'origine.

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>
  );
}

Rendez tous les itinéraires sous forme de "liste plate"

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>
  );
}

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal