Lecciones del curso
Introducción al desarrollo web full stack con React Router
<Link> y navegación en RRF
Hay muchas maneras de navegar en una aplicación construida con React Router Framework. Tenemos a los componentes <Link>
y <NavLink>
que son la mejor opción siempre que se pueda. Pero, como vimos en la lección pasada, el componente <Form>
también detonará la navegación; no te olvides de esto, te será muy útil. Tenemos también al hook useNavigate
, que es ya muy conocido dentro de la comunidad de React Router. Pero, también tendremos una herramienta del lado del servidor con la que podremos navegar: la función redirect
. Veamos pues, cada una de estas opciones con más detalle ¿te late? 🧐
Comencemos con NavLink
El componente <NavLink>
es casi lo mismo que el componente <Link>
solo que este componente está pensado para reflejar estados de navegación. Esto, nos facilitará cambiar nuestra interfaz para representar los diferentes estados de la carga; mira, veamos un ejemplo. 🔬
import { NavLink } from "react-router"; export default function Route() { return ( <nav> <NavLink to="/" end> Inicio </NavLink> <NavLink to="/dashboard" end> Panel de control </NavLink> <NavLink to="/contactos">Toda la gente</NavLink> <NavLink to="/mi-perfil">Perfil</NavLink> </nav> ); }
El solo hecho de emplear este componente en vez de <Link> será suficiente para que las clases CSS se apliquen y cambien automáticamente. ¿Que cuáles clases CSS?
a.active { color: red; } a.pending { animate: pulse 1s infinite; } a.transitioning { /* css transition is running */ }
Pues estas tres. Este componente transicionará automáticamente entre las clases active
, pending
y transitioning
. Solo añádelas a tus estilos CSS e invierte tu tiempo en decidir los bonitos colores que preferirás, en vez de estar peleándote con los ternarios en el JSX. 🤩
Ahora, que si lo tuyo es JS y andar de peleonero(a) con los ternarios en el JSX, entonces, el <NavLink>
también tiene algo para ti. 🥊
// className <NavLink to="/cursos" className={({ isActive, isPending, isTransitioning }) => [ isPending ? "pending" : "", isActive ? "active" : "", isTransitioning ? "transitioning" : "", ].join(" ") } > Todos los cursos </NavLink>
Podemos usar el callback que nos devuelve tres booleanos dentro de className
y también dentro de styles
¡y hasta de children
!
// style <NavLink to="/blog" style={({ isActive, isPending, isTransitioning }) => { return { fontWeight: isActive ? "bold" : "", color: isPending ? "red" : "black", viewTransitionName: isTransitioning ? "slide" : "", }; }} > Messages </NavLink> // children <NavLink to="/mis-videos"> {({ isActive, isPending, isTransitioning }) => ( <span className={isActive ? "active" : ""}> Mis videos </span> )} </NavLink>
Aquí hay para todos, para los que trabajan con bonitos estilo y para los mugrosos como “sho”, cómo de que no. 👨🏿🦳 👩🏼🦲👩🏼🎤 Pero si este componente es un overkill para tu caso de uso, y, solo necesitas navegar rapidito sin representar ningún estado ni estilos, entonces, el componente <Link>
es lo que buscas. 🔦
El componete <Link>
<Link>
es el componente que más usaremos para navegar dentro de nuestras aplicaciones React Router.
import { Link } from "react-router"; export default function Route() { return ( <> Te hemos enviado tu link mágico. 🧙♂️ <Link to="/">Volver al inicio</Link> </> ); }
Simple y bonito ¿apoco no?
👀 Toma en cuenta que <Link> está pensado para rutas internas de tu app, si necesitas un enlace externo, siempre podrías implementar el clásico anchor:
<a href="https://www.easybits.cloud" rel="noreferrer" target="_blank" >
.
El componente <Form>
Claro que se puede navegar con un <Form>
. Hay una lectura que te quiero recomendar para que entiendas mejor el diseño original de la plataforma. Se llama: https://hypermedia.systems/. Si puedes, dátelo. 📖
Pero, mientras tanto, veamos un ejemplo super simple con <Form>
.
<Form action="/blog"> <input type="text" name="search" /> <input type="submit" /> </Form>
Cuando enviemos un formulario así: se detonará la navegación, porque este <Form>
hará una petición GET con los inputs como searchParams
: /blog?search=react
. 😱
Este pattern
es muy útil dentro de React Router para detonar la ejecución del loader una segunda vez, pero con nuevos searchParams
. De hecho, así es como funciona el buscador de fixtergeek.com 🤠
👀 Recuerda que un formulario usa los mismos inputs para cualquier petición, ya sea GET o POST. Cuando es una petición GET los envía en forma de
searchParams
añadiéndolos en la propia URL. Pero, cuando es una petición POST, los entregará dentro de unFormData
. 🪢
No dejes de leer el libro que te digo. 😒
redirect() desde el servidor
Como te he dicho antes, yo prefiero, siempre que puedo, la manera declarativa. Osea que uso bastante el componente <Form>
incluso para navegar. Así que todo el tiempo estoy redireccionando desde el servidor. Sobre todo, dentro de las funciones action
. Para ello, tenemos a la mano el helper redirect
. ↪️
import { redirect } from "react-router"; export async function action({ request }) { const formData = await request.formData(); const newProduct = await createProduct(formData); return redirect(`/products/${newProduct.slug}`); }
Este pattern, es uno de los **más comunes en la web; pues redirect
es solo un wrapper, una utilidad, que, por debajo, emplea un Response
nativo de la fetch API. 😬
👀 Podríamos sustituir un redirect con un:
new Response.redirect(url)
. 🤯
Este helper vendrá a ser útil también en las funciones loader
del módulo de ruta. Para proteger una ruta privada, por ejemplo. 🙌🏼
import { redirect } from "react-router"; export async function loader({ request }) { const user = await getUserOrNull(request); if (!user) { return redirect("/login"); } return { user }; }
Ya para terminar: useNavigate
Este hook es para el cliente; lo podremos usar en cualquiera de nuestros componentes. 🧱
import { useNavigate } from "react-router"; export default function Route() { const navigate = useNavigate(); const handleSubmit = (event) => { // ... masajeamos y mandamos con fetcher.submit // para luego navegar, por ejemplo... navigate('/dashboard/products') // vamos a donde sea. } return (<form onSubmit={handleSubmit}> {/** */} </form>) }
No te dejes influenciar demasiado por mis ejemplos, navigate
puede usarse imperativamente (programáticamente) dentro de cualquier función; puedes usarla en un <button>
o dentro de un useEffect
; tú decides, tú eres el(la) desarrollador(a) front end. 🤷🏻♀️
👀 Aunque puedes usar este hook cuando necesites navegar sin una interacción del usuario, la documentación oficial nos recomienda evitarlo todo lo posible y preferir el uso de los otros métodos antes vistos. ⛔️
Bueno bueno, ¡mírate nomás! Ya eres todo un(a) experto(a) en las herramientas de este Framework. Ya navegas de un lado para el otro sin pedir permiso. Bien hecho mi niño. 👦🏻👧🏻