paint-brush
Técnicas avanzadas de React Router V6: ir más allá de lo básicopor@sojinsamuel
6,427 lecturas
6,427 lecturas

Técnicas avanzadas de React Router V6: ir más allá de lo básico

por Sojin Samuel11m2023/07/02
Read on Terminal Reader

Demasiado Largo; Para Leer

React Router es una herramienta increíble que nos permite crear una navegación dinámica y fluida en nuestras aplicaciones React. Existen algunas técnicas menos conocidas que pueden elevar sus habilidades de enrutamiento a un nivel completamente nuevo. Cubriremos: Manejo de la notoria página 404. Creación de un indicador de página activa para resaltar la ruta actual. Utilizando ganchos `useNavigate` y `useLocation`.
featured image - Técnicas avanzadas de React Router V6: ir más allá de lo básico
Sojin Samuel HackerNoon profile picture
0-item
1-item

Estoy muy emocionado de compartir con ustedes algunas técnicas avanzadas de React Router hoy. React Router es una herramienta increíble que nos permite crear una navegación dinámica y fluida en nuestras aplicaciones React .


Si bien se usa comúnmente para las necesidades básicas de enrutamiento, existen algunas técnicas menos conocidas que pueden elevar sus capacidades de enrutamiento a un nivel completamente nuevo.


Hoy compartiré algunos de mis favoritos que he descubierto con el tiempo.


Cubriremos:

  1. Manejo de la notoria página 404.
  2. Creación de un indicador de página activa para resaltar la ruta actual.
  3. Utilizando ganchos useNavigate y useLocation .


Cuando termine de leer este artículo, tendrá una gran comprensión de estas técnicas avanzadas de React Router y se sentirá seguro al aplicarlas en sus propios proyectos.


Entonces, ¡vamos a sumergirnos y mejorar juntos nuestras habilidades de enrutamiento!


¿Estás listo? ¡Empecemos!

Tratar con una página 404


Cuando se trabaja en proyectos más grandes, es esencial cuidar las rutas que no se pueden encontrar. A menudo nos referimos a estas rutas como rutas 404 porque devuelven el código de estado HTTP 404 cuando no se encuentra un documento en el servidor.


Por cierto, si eres un amante de los gatos, quizás disfrutes visitando http.cat .


Ahora, profundicemos en la creación de una ruta especial que se activará cuando ninguna de las otras rutas coincida con la URL actual en el navegador.

 import {BrowserRouter, Routes, Route} from "react-router-dom"; function App() { return <BrowserRouter> <Routes> <Route path="/" element={<p>Landing page</p>}></Route> <Route path="/products" element={<p>Products page</p>}></Route> <Route path="*" element={<p>404 page</p>}></Route> </Routes> </BrowserRouter> }

Al acceder a la página principal / , los usuarios serán dirigidos a la página de destino. Navegar a la página /products los llevará a la página de Productos. Sin embargo, si se accede a otros enlaces que no corresponden a una ruta específica, se mostrará la página 404.


El motivo de este comportamiento es la implementación de una <Route> especializada para la página 404, donde la propiedad de la ruta se establece en * . Esta configuración garantiza que React Router utilizará exclusivamente esta ruta cuando no se puedan combinar otras rutas. La ubicación específica de la Ruta 404 es intrascendente y se puede colocar en cualquier lugar dentro de la sección <Routes>...</Routes> , como un componente integral de la misma.

página activa

Otra forma en que las aplicaciones pueden hacer uso de las rutas de manera práctica es resaltando la página actualmente activa en el menú.


Imaginemos que tiene un menú de navegación con dos enlaces:


  1. Inicio - Este enlace lleva al usuario a la página principal / .

  2. Acerca de: este enlace lleva al usuario a la página Acerca /about .


Con React Router, es posible resaltar automáticamente el enlace About de cuando el usuario está en la ruta /about . Del mismo modo, puede resaltar el enlace Inicio cuando el usuario está en la ruta / . La mejor parte es que puedes lograr esto sin la necesidad de condicionales complejos.


Aquí hay una manera simple de hacer que funcione:

 import {NavLink} from "react-router-dom"; function getClassName({isActive}) { if (isActive) { return "active"; // CSS class } } function App() { return <ul> <li> <NavLink to="/" className={getClassName}>Home</NavLink> </li> <li> <NavLink to="/about" className={getClassName}>About</NavLink> </li> </ul> }


El código que ve arriba necesita algo de CSS para que la clase active funcione. Por lo tanto, podemos mejorarlo haciendo que el enlace del menú de la página actualmente activa aparezca en negrita y se destaque.

 .active { font-weight: bold; }


El atributo className del elemento NavLink tiene la flexibilidad de aceptar una función en lugar de solo una cadena. Cuando decida usar una función, se le dará un objeto como parámetro, y este objeto tendrá la propiedad isActive ya configurada. Para acceder fácilmente a esta propiedad dentro de la función, usamos la desestructuración al incluir {isActive} en el parámetro.


A continuación, procedemos a verificar si isActive tiene un valor verdadero. Si ese es el caso, devolveremos el nombre de la clase CSS active .


Cuando la ruta actual en React Router coincide con el atributo to del componente NavLink , la función isActive se evaluará como un valor booleano.


Como resultado, React Router incluirá sin problemas la clase active en el elemento <NavLink /> correspondiente, indicándolo como la ruta actualmente activa.

Versión más corta

Si prefiere un enfoque más corto, puede usar el operador ternario para refactorizar el código mencionado anteriormente. Este operador proporciona una forma de reemplazar una declaración if/else usando el formato: ¿ condition ? truthy expression : falsy expression .

Realmente no uso mucho el operador ternario porque a menudo puede hacer que el código sea menos legible. Sin embargo, es aceptable usarlo en este caso.


Considere lo siguiente como un ejemplo:

 function getClassName({isActive}) { if (isActive) { return "active"; } else { return ""; } }


Puede sustituir el código anterior con el siguiente enfoque:

 function getClassName({isActive}) { return isActive ? "active" : ""; }


Simplemente debe asegurarse de que la declaración de devolución se coloque fuera del operador ternario. Cuando la condición isActive es verdadera, la expresión después de ? se ejecutará "active" . De lo contrario, la expresión después de : se ejecutará "" .


Ahora, podemos eliminar la necesidad de una definición de función separada llamada getClassName . En su lugar, podemos usar una función de flecha como esta: ({isActive}) => isActive ? "active" : "" .


Si encuentra este cambio demasiado difícil de leer, puede continuar usando una función separada como antes.

El código final se vería así:

 import {NavLink} from "react-router-dom"; function App() { return <ul> <li> <NavLink to="/" className={({isActive}) => isActive ? "active" : ""}>Home</NavLink> </li> <li> <NavLink to="/about" className={({isActive}) => isActive ? "active" : ""}>About</NavLink> </li> </ul> }

Oh chico, ¡prácticamente puedo escuchar tus pensamientos!

Sojin, has ido y roto el principio SECO, ¿no es así?

Este es solo un ejemplo. No hay necesidad de ponerse nervioso 😀

Elegir entre Link y NavLink: ¿Qué los distingue?

Es posible que ya haya notado que estoy usando NavLink en lugar de nuestro amigo habitual, Link . Pero no te preocupes, déjame explicarte por qué. Verá, el componente <Link /> no le permite usar una definición de función para la propiedad className . Sí, puede ser sorprendente, pero así es cuando trabajas con <Link /> .


Un error común que he visto es que los desarrolladores junior de React intentan usar definiciones de función en la propiedad className de un componente <Link /> , que simplemente no funciona.


Si te interesa, puedo escribir un artículo sobre este tema. ¡Solo házmelo saber en los comentarios!

usarNavegar

En determinadas circunstancias, es posible que deba reubicar páginas mediante programación dentro de su aplicación React. Por ejemplo, para redirigir al visitante a una página específica, puede enviar una solicitud y esperar la respuesta.


Aquí están algunos ejemplos:

  • Si el usuario no ha iniciado sesión, envíelo a la página de inicio de sesión.
  • Después de que la solicitud getLogin se haya completado con éxito, redirija al usuario a /dashboard .


Esto requiere el uso del gancho useNavigate() , que devuelve una función que puede usar para redirigir al usuario mediante programación a una nueva ruta.


Echar un vistazo:

 import React, {useEffect} from "react"; import {useNavigate} from "react-router-dom"; function HelpPage() { const navigate = useNavigate(); useEffect(() => { const isLoggedIn = window.localStorage.getItem("isLoggedIn"); if (!isLoggedIn) { navigate("/login"); } }, []); return <h2>Help page</h2>; }

¡Usar BrowserRouter es esencial!

En este ejemplo, estamos comprobando si localStorage tiene un valor asignado a la clave isLoggedIn . Si no es así, redirigiremos al usuario a la página /login mediante la función navigate("/login") .


Para que funcione, solo recuerde usar el gancho useNavigate() dentro de un componente que está anidado dentro del componente <BrowserRouter /> . De lo contrario, no funcionará correctamente.


Por ejemplo, el siguiente ejemplo no funcionará:

 import React from "react"; import {BrowserRouter, useNavigate} from "react-router-dom"; function App() { // ❌ This breaks because the component was not wrapped by BrowserRouter, but its children are. const history = useNavigate(); return <BrowserRouter> {/* ... */} </BrowserRouter>; }

Si está tratando de usar el gancho useNavigate() dentro del componente App() , es posible que tenga un pequeño contratiempo. Eso es porque no funcionará a menos que envuelva el componente App() con <BrowserRouter /> .


¡Pero no te preocupes!


La buena noticia es que todos los componentes secundarios dentro de la aplicación serán envueltos automáticamente por <BrowserRouter /> , por lo que puede usar felizmente useNavigate() en esos componentes secundarios sin ningún problema.


Sin embargo, si realmente necesita usar useNavigate() en el propio componente <App /> , hay una solución simple. Solo necesita crear un componente principal que envuelva <App /> y asegúrese de mover el <BrowserRouter /> dentro de ese componente principal. Una vez que hagas eso, estarás listo y podrás usar useNavigate() en el componente <App /> para el contenido de tu corazón 💗

Garantizar la accesibilidad y el uso adecuado de enlaces

Cuando se trata de hacer que su sitio web sea accesible, es importante prestar atención a cómo están estructurados sus enlaces. Para garantizar eso, se recomienda usar elementos <Link /> en lugar de otros métodos.


¿Por qué?


Bueno, estos elementos se representarán automáticamente como etiquetas <a> , que son conocidas por sus características de accesibilidad .

Ahora, aquí hay un consejo amistoso: evite reemplazar sus elementos <Link /> normales con el método .push() proporcionado por useNavigate() . Este método solo debe utilizarse en los casos en que no sea posible utilizar un elemento <Link /> .


¿Cuándo sucede eso?

Por lo general, es cuando necesita redirigir a los usuarios mediante programación en función de cierta lógica, como el resultado de una operación fetch() .

useUbicación

¿Qué sucede si desea ejecutar un fragmento de código cada vez que React Router lo lleva a una nueva dirección?

Puede lograrlo fácilmente con la ayuda del enlace useLocation . Pero antes de profundizar en los detalles, exploremos algunos escenarios en los que esto puede resultar útil. Uno de los casos de uso más comunes es enviar un evento de vista de página a su servicio de análisis, como Google Analytics.


Sin embargo, vale la pena mencionar que Google Analytics 4 ahora se encarga de esto automáticamente, por lo que no necesariamente tiene que implementarlo usted mismo.


Sin embargo, aprender sobre el enlace useLocation sigue siendo valioso, ya que puede encontrar otros propósitos para él. Por ejemplo, puede usarlo para integrarse con otras bibliotecas y servicios de análisis, o para ejecutar acciones específicas basadas en las rutas visitadas.


¡Las posibilidades son infinitas!

gancho useLocation

El enlace useLocation es muy útil porque le brinda información sobre la ruta que se está utilizando actualmente.


Aquí hay una guía amigable sobre cómo usar el enlace useLocation:

 import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); console.log(location.pathname); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);


Ahora, puede acceder a la información de la ruta a través de la variable de ubicación. Es un objeto que contiene el pathname actual.


Para averiguar qué ruta está navegando el usuario actualmente, simplemente use location.pathname . Le dará algo como / , /about , o cualquier otra ruta que haya configurado.


Recuerde, al igual que con el enlace useNavigate , es importante que su código se ejecute dentro de un componente que está envuelto por <BrowserRouter /> . De lo contrario, el enlace useLocation no hará su magia.

Responder a los cambios de ubicación

Cuando la ubicación cambia, puede utilizar el enlace useLocation para acceder a la ruta URL actual en React Router. Al envolver su código con un enlace useEffect y establecer la dependencia en location , puede ejecutar una pieza específica de código siempre que haya una navegación a una nueva URL.


Aquí hay un ejemplo de cómo hacerlo:

 import React, {useEffect} from "react"; import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); // run a piece of code on location change useEffect(() => { console.log(location.pathname); // send it to analytic, or do some conditional logic here }, [location]); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);

Cada vez que el usuario se mueve a una nueva ruta durante la navegación, el código dentro del enlace useEffect se ejecutará y hará lo suyo. Es básicamente una forma de asegurarse de que se ejecute un código específico siempre que haya un cambio en el objeto de ubicación.

Buen trabajo, ahora eres un experto en React Router 🥳

Para concluir, este artículo le ha brindado una comprensión más profunda de React Router. Si bien es posible que no use todas las funciones discutidas aquí. Aún así, es fantástico que estés al tanto de ellos. Si alguna vez necesita incorporar una funcionalidad similar en el futuro, sabe exactamente dónde buscar. Por lo tanto, asegúrese de guardar o marcar esta publicación para una fácil referencia. Y recuerde, si tiene alguna pregunta o necesita más ayuda, no dude en comunicarse conmigo en Twitter. ¡Estoy aqui para ayudar!