Die Hooks von React Router

Avatar of Agney Menon
Agney Menon am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

React Router 5 nutzt die Kraft von Hooks und hat vier verschiedene Hooks zur Unterstützung des Routings eingeführt. Wenn Sie eine schnelle Einführung in die neuen Muster von React Router suchen, wird Ihnen dieser Artikel nützlich sein. Bevor wir uns jedoch mit Hooks befassen, beginnen wir mit einem neuen Muster für das Rendern von Routen.

Vor React Router 5

// When you wanted to render the route and get router props for component
<Route path="/" component={Home} />


// Or when you wanted to pass extra props
<Route path="/" render={({ match }) => <Profile match={match} mine={true} />}>

Bei der Verwendung der component-Syntax werden die Routen-Props (match, location und history) implizit an die Komponente übergeben. Sie müssen jedoch auf render geändert werden, sobald Sie zusätzliche Props an die Komponente übergeben möchten. Beachten Sie, dass das Hinzufügen einer Inline-Funktion zur component-Syntax dazu führt, dass die Komponente bei jedem Rendern neu montiert wird.

Nach React Router 5

<Route path="/">
  <Home />
</Route>

Beachten Sie, dass keine implizite Übergabe von Props an die Home-Komponente erfolgt. Aber ohne Änderungen an der Route selbst können Sie der Home-Komponente beliebige zusätzliche Props hinzufügen. Sie können nicht mehr den Fehler machen, die Komponente bei jedem Rendern neu zu montieren, und das ist die beste Art von API.

Aber jetzt werden die Routen-Props nicht mehr implizit übergeben, also wie greifen wir auf match, history oder location zu? Müssen wir alle Komponenten mit withRouter umschließen? Hier kommen die Hooks ins Spiel.

Beachten Sie, dass Hooks in Version 16.8 von React eingeführt wurden. Sie müssen sich also über dieser Version befinden, um sie verwenden zu können.

useHistory

  • Bietet Zugriff auf die history-Prop in React Router
  • Bezieht sich auf die Abhängigkeit des history-Pakets, das der Router verwendet
  • Ein primärer Anwendungsfall wäre das programmatische Routing mit Funktionen wie push, replace usw.
import { useHistory } from 'react-router-dom';

function Home() {
  const history = useHistory();
  return <button onClick={() => history.push('/profile')}>Profile</button>;
}

useLocation

  • Bietet Zugriff auf die location-Prop in React Router
  • Es ist ähnlich wie window.location im Browser selbst, aber dies ist überall zugänglich, da es den Router-Status und den Standort repräsentiert.
  • Ein primärer Anwendungsfall hierfür wäre der Zugriff auf Query-Parameter oder den vollständigen Routen-String.
import { useLocation } from 'react-router-dom';

function Profile() {
  const location = useLocation();
  useEffect(() => {
    const currentPath = location.pathname;
    const searchParams = new URLSearchParams(location.search);
  }, [location]);
  return <p>Profile</p>;
}

Da die location-Eigenschaft unveränderlich ist, ruft useEffect die Funktion jedes Mal auf, wenn sich die Route ändert, was sie perfekt für die Verarbeitung von Suchparametern oder dem aktuellen Pfad macht.

useParams

  • Bietet Zugriff auf Suchparameter in der URL
  • Dies war früher nur mit match.params möglich.
import { useParams, Route } from 'react-router-dom';

function Profile() {
  const { name } = useParams();
  return <p>{name}'s Profile</p>;
}

function Dashboard() {
  return (
    <>
      <nav>
        <Link to={`/profile/ann`}>Ann's Profile</Link>
      </nav>
      <main>
        <Route path="/profile/:name">
          <Profile />
        </Route>
      </main>
    </>
  );
}

useRouteMatch

  • Bietet Zugriff auf das match-Objekt
  • Wenn es ohne Argumente übergeben wird, gibt es die nächstgelegene Übereinstimmung in der Komponente oder ihren übergeordneten Elementen zurück.
  • Ein primärer Anwendungsfall wäre die Konstruktion von verschachtelten Pfaden.
import { useRouteMatch, Route } from 'react-router-dom';

function Auth() {
  const match = useRouteMatch();
  return (
    <>
      <Route path={`${match.url}/login`}>
        <Login />
      </Route>
      <Route path={`${match.url}/register`}>
        <Register />
      </Route>
    </>
  );
}

Sie können useRouteMatch auch verwenden, um eine Übereinstimmung abzurufen, ohne eine Route zu rendern. Dies geschieht durch Übergabe des Standortarguments.

Betrachten Sie beispielsweise, dass Sie Ihr eigenes Profil unter /profile und das Profil einer anderen Person rendern möchten, wenn die URL den Namen der Person enthält: /profile/dan oder /profile/ann. Ohne die Verwendung des Hooks würden Sie entweder eine Switch schreiben, beide Routen auflisten und sie mit Props anpassen. Aber jetzt können wir das mit dem Hook tun

import {
  Route,
  BrowserRouter as Router,
  Link,
  useRouteMatch,
} from 'react-router-dom';

function Profile() {
  const match = useRouteMatch('/profile/:name');

  return match ? <p>{match.params.name}'s Profile</p> : <p>My own profile</p>;
}

export default function App() {
  return (
    <Router>
      <nav>
        <Link to="/profile">My Profile</Link>
        <br />
        <Link to={`/profile/ann`}>Ann's Profile</Link>
      </nav>
      <Route path="/profile">
        <Profile />
      </Route>
    </Router>
  );
}

Sie können auch alle Props auf Route wie exact oder sensitive als Objekt mit useRouteMatch verwenden.

Zusammenfassung

Die Hooks und die explizite Route bringen einen versteckten Vorteil mit sich. Nachdem ich diese Techniken in mehreren Workshops gelehrt habe, bin ich zu der Erkenntnis gelangt, dass sie helfen, viel Verwirrung und Komplexität zu vermeiden, die mit den früheren Mustern einhergingen. Es gibt plötzlich weitaus weniger ungewollte Fehler. Sie werden sicherlich dazu beitragen, Ihren Router-Code wartbarer zu machen, und Sie werden es viel einfacher finden, auf neue React Router-Versionen zu aktualisieren.