Contenido del curso
Introducción a nuestro proyecto
¡Atraparlos ya!
React.js + Redux
Middlewares
Avanzando la ui
Inmutabilidad
Avanzado
Despedida del curso
Criando middlewares personalizados no Redux
Resumen
Los middlewares en Redux son fragmentos de código que se ejecutan entre el momento en que se dispara una acción y el instante en que llega al reducer. Aprenderás a crear middlewares personalizados desde cero, combinarlos con enhancers y aplicarlos a tu store para registrar acciones, modificar payloads y ampliar las capacidades de tu aplicación.
¿Qué es un middleware en Redux y para qué sirve?
Un middleware es una pieza de código que intercepta cada acción antes de que llegue al reducer. Esa intercepción te abre un abanico enorme de posibilidades: registrar errores, enviarlos a gestores como Sentry, hacer fetch de datos o depurar tu aplicación con detalle.
¿Para qué se usa un middleware en Redux? Para ejecutar lógica entre el dispatch de una acción y su llegada al reducer. Te permite loggear, modificar el payload, manejar efectos secundarios o conectar con servicios externos.
Antes de escribir código, conviene tener claros tres términos que aparecen una y otra vez cuando trabajas con el store [01:00].
¿Qué diferencia hay entre store creator, enhancer y compose?
- Store creator: la función que crea tu store de Redux.
- Enhancer: una función de orden superior que recibe un store creator y devuelve una versión potenciada con superpoderes. La línea que añadiste para usar Redux DevTools es justamente un enhancer porque amplía la funcionalidad del estado y te permite inspeccionarlo desde el navegador.
- Compose: utilidad de programación funcional que combina funciones de derecha a izquierda. La usarás cuando necesites aplicar varios enhancers a la vez.
Con estas piezas claras, ya puedes pasar a la práctica.
¿Cómo crear un middleware logger personalizado?
El primer middleware que vas a construir registra cada acción disparada en la consola. Para empezar, crea una carpeta middlewares dentro de src y un archivo index.js [02:30].
La estructura de un middleware en Redux es muy específica. Se trata de una función curried, es decir, una función que retorna otra función, y así sucesivamente:
js const logger = (store) => (next) => (action) => { console.log(action); next(action); };
export default logger;
Cada parámetro tiene un rol concreto:
store: es el store de tu aplicación.next: la función que despacha la acción al reducer. Si no la llamas, la acción nunca llega.action: la información de lo que está ocurriendo.
¿Qué pasa si no llamo a next dentro de un middleware? La acción se queda atrapada en el middleware y nunca llega al reducer, así que el estado no cambia.
¿Cómo combinar varios enhancers con compose y applyMiddleware?
En tu index.js principal, necesitas combinar el enhancer de Redux DevTools con tu nuevo middleware. Para eso, importa compose y applyMiddleware desde Redux:
js import { createStore, compose, applyMiddleware } from 'redux'; import logger from './middlewares';
const composedEnhancers = compose( window.REDUX_DEVTOOLS_EXTENSION_COMPOSE || compose, applyMiddleware(logger) );
const store = createStore(reducer, composedEnhancers);
No puedes pasar el logger directamente a compose, porque la estructura de parámetros curried no se respetaría. Por eso applyMiddleware envuelve el middleware y lo entrega a compose con el formato correcto [05:20].
Al abrir la consola del navegador verás cada acción con su tipo, su payload y su timestamp. Confirmas así que el middleware funciona.
¿Cómo modificar el payload de una acción desde un middleware?
Un middleware no solo observa: también puede transformar la información antes de que llegue al reducer. Imagina que, sin importar qué Pokémon devuelva la API, quieres añadir uno personalizado al inicio de la lista [07:10].
Creas un middleware llamado featuring con la misma estructura curried:
js const featuring = (store) => (next) => (actionInfo) => { const modifiedPokemons = [ { name: 'Eddie' }, ...actionInfo.action.payload, ];
const updatedAction = { ...actionInfo, action: { ...actionInfo.action, payload: modifiedPokemons, }, };
next(updatedAction); };
La lógica es directa: tomas todo lo que viene en actionInfo.action.payload, lo desestructuras con el operador spread, y antepones tu Pokémon personalizado. Después construyes una updatedAction que conserva el resto de propiedades intactas y reemplaza solo el payload.
¿Cómo aplicar varios middlewares al mismo store?
applyMiddleware acepta tantos middlewares como quieras pasarle. Solo necesitas listarlos en el orden en que deben ejecutarse:
js applyMiddleware(logger, featuring)
¿Puedo usar más de un middleware en Redux? Sí.
applyMiddlewarerecibe múltiples middlewares como argumentos y los ejecuta en cadena, en el orden en que los declares.
Al recargar el navegador, verás a Eddie como primer Pokémon de la lista. Y si pides un offset a la API para traer los siguientes 151 Pokémon, toda la lista cambia menos Eddie, porque ese se inyecta dentro del middleware antes de llegar al reducer [10:15].
Este ejemplo es sencillo, pero abre la puerta a casos reales: enriquecer respuestas, filtrar datos sensibles, transformar formatos o disparar lógica condicional.
¿Qué middleware personalizado se te ocurre añadir a este proyecto? Cuéntalo en los comentarios y comparte tu implementación.