Maison  >  Questions et réponses  >  le corps du texte

Création d'itinéraires protégés : un guide pratique utilisant React-Router-dom

<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粉596191963P粉596191963444 Il y a quelques jours462

répondre à tous(2)je répondrai

  • P粉253518620

    P粉2535186202023-08-25 09:42:47

    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

    répondre
    0
  • P粉505917590

    P粉5059175902023-08-25 00:11:28

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

    répondre
    0
  • Annulerrépondre