Diagrama del principio de implementación de History API y React Router.

El enrutador es una función esencial para desarrollar aplicaciones React, entonces, ¿cómo lo implementa React Router?

¡Leamos el código fuente de React Router hoy!

Primero, aprendamos la API History, que es la base.

¿Qué es la historia?

Es esta cosa:

imagen

Abrí una nueva pestaña y visité baidu.com, sougou.com, taobao.com.

Mantenga presionado el botón Atrás, aparecerá el historial, esto es el historial.

En ningún lugar:

imagen

historia.longitud 是 5

imagen

Haga clic en el botón Atrás dos veces o ejecute History.back() dos veces

imagen

regresará aquí:

imagen

En este momento, la longitud de la historia sigue siendo 5.

imagen

Porque aún se conserva la historia del antes y el después:

imagen

imagen

Además de cambiar entre el historial con History.back e History.forward, también puedes usar History.go

El valor del parámetro es delta:

History.go(0) es para actualizar la página actual.

History.go(1) es uno directo, equivalente a History.forward()

History.go(-1) es retroceder uno, lo que equivale a History.back()

Por supuesto, también puedes usar History.go(-2), History.go(3), etc.

imagen

Por ejemplo, cuando ejecuto History.go (-2), puedo saltar directamente de taobao.com a sogou.com.

imagen

También puedes reemplazar el historial actual con History.replaceState:

imagen

history.replaceState({
    
    aaa:1}, '', 'https://www.baidu.com?wd=光')

El primer parámetro es el estado, el segundo parámetro es el título y el tercero es la URL a reemplazar.

Sin embargo, el segundo parámetro básicamente no es compatible, pero se puede obtener el estado.

Por ejemplo, reemplazoState con una nueva URL en la página https://www.baidu.com:

imagen

La historia no ha cambiado antes y después, solo ha cambiado la actual:

imagen

Eso es todo:

imagen

Por supuesto, también puedes usar History.pushState para agregar un nuevo historial:

history.pushState({
    
    bbb:1}, '', 'https://www.baidu.com?wd=东');

imagen

Pero hay un fenómeno, es decir, la historia posterior desapareció:

imagen

imagen

Es decir, queda así:

imagen

¿por qué?

Porque cuando eres History.pushState, entra en conflicto con el historial posterior, es decir, bifurcaciones:

imagen

En este momento, naturalmente, solo se puede conservar una sucursal, que es la más reciente.

En este momento, la longitud de la historia es 3.

imagen

Hasta ahora, hemos utilizado las API de longitud, ir, retroceder, avanzar, pushState, replaceState y estado del historial.

También hay un History.scrollRestoration que se utiliza para preservar la posición de desplazamiento:

Hay dos valores, automático y manual, el predeterminado es automático, es decir, localizará automáticamente la última posición de desplazamiento y no funcionará si está configurado en manual.

Por ejemplo, visité Baidu en esta ubicación:

imagen

Abra una nueva página y regrese a:

imagen

Todavía está en la posición a la que se desplazó la última vez.

Esto se debe a que su historial.scrollRestoration es automático.

imagen

Configurémoslo en manual y probémoslo:

imagen

imagen

En este momento, incluso si se desplaza hacia abajo, volverá a la parte superior cuando regrese.

Además, hay un evento relacionado con la historia: popstate

Cuando navegas por el historial, se activará popstate, como History.forwad, History.back, History.go.

Pero History.pushState, History.replaceState no activará popstate.

Probemos:

imagen

history.pushState({
    
    aaa:1}, '', 'https://www.baidu.com?#/aaa');

history.pushState({
    
    bbb:2}, '', 'https://www.baidu.com?#/bbb');

Agregué dos historias a la página pushState de www.baidu.com.

Hay un total de 4 páginas de navegación:

imagen

Luego escucho el evento popstate:

imagen

window.addEventListener('popstate', event => {console.log(event)});

La ejecución de History.back y History.forward activará el evento popstate:

imagen

El evento contiene el estado y la URL actual también se puede obtener de target.location

imagen

Pero cuando usas History.pushState, History.replaceState no lo activa:

imagen

Es decir, agregar y modificar el historial no activará popstate, solo al navegar entre estados.

En resumen, hemos repasado la historia de los eventos api y popstate.

En base a estos, se puede implementar React Router.

Algunos estudiantes dijeron, ¿no hay un evento de cambio de hash?

De hecho, eso es para monitorear los cambios de hash.

imagen

imagen

En base a esto, también se puede implementar el enrutador, pero obviamente, hashchange solo puede monitorear los cambios de hash, y popstate no es solo cambios de hash, sino que tiene más funciones.

Entonces usar el evento popstate es suficiente.

De hecho, en el enrutador de reacción, solo se usa el evento popstate y no el evento hashchange:

imagen

imagen

A continuación, echemos un vistazo más de cerca a cómo se implementa React Router.

Crea un proyecto de reacción:

npx create-react-app react-router-test

imagen

Instale el paquete reaccionar-router:

npm install react-router-dom

Luego escriba el siguiente código en index.js:

import React from 'react';
import ReactDOM from 'react-dom/client';
import {
    
    
  createBrowserRouter,
  Link,
  Outlet,
  RouterProvider,
} from "react-router-dom";

function Aaa() {
    
    
  return <div>
    <p>aaa</p>
    <Link to={
    
    '/bbb/111'}>to bbb</Link>
    <br/>
    <Link to={
    
    '/ccc'}>to ccc</Link>
    <br/>
    <Outlet/>
  </div>;
}

function Bbb() {
    
    
  return 'bbb';
}

function Ccc() {
    
    
  return 'ccc';
}

function ErrorPage() {
    
    
  return 'error';
}

const routes = [
  {
    
    
    path: "/",
    element: <Aaa/>,
    errorElement: <ErrorPage/>,
    children: [
      {
    
    
        path: "bbb/:id",
        element: <Bbb />,
      },
      {
    
    
        path: "ccc",
        element: <Ccc />,
      }    
    ],
  }
];
const router = createBrowserRouter(routes);

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<RouterProvider router={
    
    router} />);

Cree un enrutador a través de createBrowserRouter del paquete react-router-dom y pase la configuración de rutas.

Luego pase el enrutador al RouterProvider.

Hay una ruta raíz /, dos rutas secundarias /bbb/:id y /ccc

Ejecute el servicio de desarrollo:

npm run start

Bajo la prueba:

imagen

Aquí se representan los componentes correspondientes a las subrutas.

Cuando no hay una ruta correspondiente, se devolverá una página de error:

imagen

Entonces, ¿cómo se hizo realidad?

Realizamos la depuración de puntos de interrupción:

imagen

Cree un archivo de configuración de depuración launch.json y luego cree una configuración de depuración de tipo chrome:

imagen

Haga un punto de interrupción en createBrowserRouter:

imagen

Haga clic en depurar:

imagen

El código se romperá aquí:

imagen

Haga clic en entrar para ingresar a la función:

Llama a createRouter:

imagen

La historia se transmite aquí.

Esta no es una API de historia nativa, sino un contenedor:

Simplemente concéntrese en los cuatro métodos de escuchar, enviar, reemplazar y listo:

imagen

imagen

escuchar es escuchar eventos popstate.

Y empujar, reemplazar y listo son encapsulaciones de la API de historial:

imagen

imagen

Además, el historial también encapsula el atributo de ubicación, por lo que no es necesario buscarlo usted mismo desde la ventana.

Luego createRouter hará una comparación entre la configuración de rutas y la ubicación actual:

imagen

imagen

matchRoutes aplanará las rutas anidadas y hará coincidir la ubicación:

imagen

Luego, el componente a renderizar y las subrutas que contiene coinciden:

imagen

De esta manera, cuando se renderiza el árbol de componentes, se sabe qué componentes renderizar:

imagen

Es para rendir el resultado del partido.

Esto completa el renderizado del componente correspondiente a la ruta:

imagen

Este es el proceso:

imagen

Al hacer clic en el enlace para cambiar de ruta:

imagen

Se ejecutará el método de navegación:

imagen

imagen

Luego vino el proceso de matchRoutes:

imagen

Después de la coincidencia, pushState o replaceState modificarán el historial y luego actualizarán el estado:

imagen

Luego se activa setState y el árbol de componentes se volverá a representar:

imagen

imagen

Este es el proceso:

imagen

router.navigate pasará a una nueva ubicación y luego comparará las rutas para encontrar una ruta coincidente.

Luego, pushState modificará el historial y activará setState de reaccionar para volver a renderizar. Al volver a renderizar, los componentes coincidentes actuales se renderizarán a través de renderMatches.

Al renderizar en Outlet, los componentes actuales que deben renderizarse se sacarán del contexto para renderizar:

imagen

imagen

Este es el proceso de renderizado cuando el enrutador renderiza por primera vez y cuando se hace clic en el enlace.

¿Qué pasa cuando se hace clic en los botones de avance y retroceso?

Esto es para escuchar popstate y luego navegar:

imagen

imagen

imagen

El proceso de seguimiento es el mismo.

imagen

Mirando hacia atrás, de hecho, las rutas del enrutador de reacción en realidad admiten estos dos métodos de configuración:

imagen

imagen

Mismo efecto.

Puedes ver por qué mirando el código fuente:

En primer lugar, el componente Ruta es un componente vacío, nada:

imagen

En el componente Rutas, los parámetros de todos los subcomponentes se eliminarán y se convertirán en configuraciones de ruta uno por uno:

imagen

imagen

¿No es el resultado el mismo que la configuración del objeto?

Resumir

Aprendimos el principio de implementación de la API histórica y React Router.

La API de historial tiene estos:

  • longitud: el número de la historia
  • adelante: avanzar uno
  • atrás: atrás uno
  • ir: adelante o atrás n
  • pushState: agregar un historial
  • replaceState: reemplaza el historial actual
  • scrollRestoration: guarde la posición de desplazamiento, el valor es automático o manual; si es manual, debe configurar la posición de desplazamiento usted mismo

Además, existen eventos popstate que pueden monitorear la navegación de History.go, History.back e History.forward para obtener la ubicación más reciente.

Tenga en cuenta aquí que pushState y replaceState no pueden desencadenar eventos popstate. Es decir, navegar entre el historial (ir, retroceder, avanzar) puede activar el estado emergente, pero modificar el historial (empujar, reemplazar) no puede activarlo.

React Router se implementa en función de estas API históricas.

Al renderizar por primera vez, coincidirá según la ubicación y las rutas configuradas, y renderizará los componentes coincidentes.

Después de hacer clic en el enlace, la ubicación y las rutas coincidirán, y luego History.pushState modificará el historial, y luego setState de reaccionar activará la nueva representación.

Al avanzar y retroceder, es decir, cuando se ejecutan History.go, History.back e History.forward, se activará popstate, este es el mismo proceso en este momento, la ubicación y las rutas coinciden, y luego se modifica History.pushState. historial, y luego, a través de reaccionar setState, se activa una nueva representación.

Al renderizar, el componente Outlet se usará para representar subrutas y useXxx se usará para recuperar información coincidente, que se pasa a través del contexto.

Este es el principio de implementación de React Router, que es inseparable de la API histórica.

Supongo que te gusta

Origin blog.csdn.net/weixin_44733660/article/details/132272938
Recomendado
Clasificación