Lecciones del curso

Introducción al desarrollo web full stack con React Router

RRv7 como puente a React 19
5m
Todo sobre rutas
6m
Todas las piezas de un Route Module
7m
Cargando datos desde la base de datos
4m
Actions y mutaciones
7m
Componente <Link> y navegación
5m
UI Patterns: Pending & Optimistic
4m
¿Cómo sustituir un useEffect?
3m
Tipado seguro de extremo a extremo
1m
Testing con RRv7
1m
Instalación
1m
Estrategias de renderizado
3m

¿Cómo sustituir un useEffect?

La función loader de React Router es una de las herramientas más útiles del framework; nos ayuda a cargar datos desde la base de datos, pues esta función se ejecuta en el servidor. Pero, no es la única función que podemos usar para conseguir datos; también tenemos a la mano al clientLoader que, como su nombre lo sugiere, se ejecuta en el cliente. ✅

Con clientLoader podemos sustituir al useEffect

Si necesitamos cargar datos desde el cliente, puede que rápido pensemos en usar un useEffect, pues useEffect se ejecuta solo en el cliente. Pero, React Router nos provee de una herramienta mucho mejor que puede correr en paralelo junto con el render. ✌🏼

export const clientLoader = async ({params}) => { const response = await fetch(`/api/users/${params.userId}`); return await res.json(); }

De esta forma, podemos conseguir datos usando los endpoints de nuestras rutas de recursos o cualquier otro servicio o API . 🤯

¿Dónde se coloca lo conseguido por el clientLoader?

Con Remix teníamos el hook: useLoaderData(), pero ahora, en React Router, podemos acceder a estos datos directamente en los props de la ruta:

export default function Route({loaderData}) { const { displayName, email, photoURL } = loaderData; return ( <> <img src={photoURL} alt="avatar" /> <h1>{displayName}</h1> <p>{email}</p> </> ); }

Así, nuestra app renderizará instantáneamente; mientras en paralelo, consigue los datos que necesita. ¡Y todo desde el cliente!

👀 Si queremos tipado seguro de extremo a extremo (end to end type safety), podemos tipar los props así: ({loaderData}: Route.ComponentProps). Hablaremos más de esta utilidad de tipos en la siguiente lección. 🤖

Carga de datos en modo estático

React Router incluye nuevas habilidades para generar contenido estático (SSG). Esto es, que puede crear páginas o archivos HTML que se crean al momento de hacer el build de producción. Muy similar a lo que hace Astro o Hugo; pero con React Router, podemos cargar los datos al momento de crear el build. 🙀

// react-router.config.ts export default { async prerender() { return ["/users/blissmo", "/blog/static-welcome"] }, }

Todas las rutas que agreguemos en este array que devuelve la función prerender del archivo de configuración, serán rutas estáticas. Mientras que el resto de nuestras rutas renderizarán de forma usual. ¡Lo cuál es super útil! 🤩 

Esto es perfecto, por ejemplo, para un blog. 📑

Podemos combinar todas estas herramientas

Lo mejor es que todas estas opciones que React Router nos ofrece ahora: se pueden combinar. Así, un loader puede cargar datos para pre-renderizar, pero aún podemos usar clientLoader para conseguir más datos, una vez en el cliente.

import { db } from "../db"; export async function loader({ params }) { return db.posts.findMany({ where: { author: params.authorId }, take: 4, select:{ slug: true, title: true }, orderBy: { createdAt: 'desc' } }) } export async function clientLoader({params}) { const url = `/api/posts?author=${params.authorId}&take=100&skip=4` return fetch(url).then(res=>res.json()) } export default function Product({loaderData: posts}) { return ( <> {posts.map(post=><PostCard post={post} key={post.id} />)} </> ); }

En este ejemplo, debes notar que tenemos los dos tipos de loaders trabajando juntos. El loader, en el servidor, carga solo los primeros 4 posts. Estos posts podrían pre-renderizarse. Pero, además, el clientLoader puede conseguir muchos más una vez que la app está corriendo en el cliente; lo que convierte nuestra página web en un sitio pre-renderizado y SPA al mismo tiempo. ¡Una locura! 😲 Y lo mejor: es que todo esto se puede poner en la cache tanto en el cliente como en el servidor. 👽

¿Genial no? Con todo esto: ¿quién podría extrañar a Next? 😜