Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Una (breve) historia de Redux
2011: Frameworks MVC de JavaScript
Los primeros frameworks MVC de JavaScript como AngularJS, Ember y Backbone presentaban problemas. AngularJS intentaba imponer una separación entre "controladores" y plantillas, pero nada impedía escribir <div onClick="$ctrl.some.deeply.nested.field = 123"> en una plantilla. Mientras tanto, Backbone se basaba en emisores de eventos: Modelos, Colecciones y Vistas podían emitir eventos. Un Modelo podía emitir un evento "change:firstName", y las Vistas se suscribían a ellos. Pero cualquier código podía suscribirse a esos eventos y ejecutar más lógica, lo que podía desencadenar más eventos.
Esto hacía que estos frameworks fueran muy difíciles de depurar y mantener. Era posible que actualizar un campo en un modelo desencadenara docenas de eventos y lógica dispersa por la aplicación, o que cualquier plantilla pudiera modificar el estado en cualquier momento, lo que hacía imposible predecir qué ocurriría al realizar una actualización de estado.
2014: Flux
Hacia 2012-2013, cuando React se lanzó públicamente, Facebook ya lo usaba internamente desde hacía un par de años. Uno de los problemas que encontraron fue que tenían múltiples componentes UI independientes que necesitaban acceder a los mismos datos, como "cuántas notificaciones sin leer hay", pero les resultaba difícil organizar esta lógica usando código al estilo Backbone.
Facebook finalmente ideó un patrón llamado "Flux": crear múltiples Stores singleton, como PostsStore y CommentsStore. Cada instancia de Store se registraba en un Dispatcher, y la única forma de activar una actualización era llamar a Dispatcher.dispatch({type: "somethingHappened"}). Este objeto plano se denominaba "acción". La idea era semcentralizar la lógica de actualización de estado: ningún fragmento aleatorio de la app podía mutar el estado directamente, y todas las actualizaciones serían predecibles.
Facebook anunció este concepto de "Arquitectura Flux" hacia 2014, pero no proporcionó una librería completa que implementara el patrón. Esto llevó a la comunidad React a crear docenas de librerías inspiradas en Flux con variaciones del patrón.
2015: El nacimiento de Redux
A mediados de 2015, Dan Abramov comenzó a construir otra librería inspirada en Flux, llamada Redux. La idea era demostrar la "depuración mediante viaje en el tiempo" para una charla técnica. La librería se diseñó usando el patrón Flux, pero aplicando principios de programación funcional. En lugar de instancias de Store, usaba funciones reductoras predecibles que realizaban actualizaciones inmutables. Esto permitía saltar adelante y atrás en el tiempo para ver cómo lucía el estado en distintos puntos. También hacía el código más directo, comprobable y comprensible.
Redux salió en 2015 y rápidamente desplazó a todas las demás librerías inspiradas en Flux. Fue adoptado tempranamente por desarrolladores avanzados del ecosistema React, y para 2016 muchos afirmaban que "si usas React, debes usar Redux también". (Francamente, ¡esto llevó a mucha gente a usar Redux donde no era necesario!)
También cabe destacar que en ese momento, React solo tenía su API Context legacy, que estaba prácticamente rota: no podía propagar valores actualizados correctamente. Así que era posible poner emisores de eventos en Context y suscribirse a ellos, pero no se podía usar para datos simples. Esto hizo que mucha gente adoptara Redux porque era una forma consistente de propagar valores actualizados por toda la aplicación.
Dan dijo desde el principio que "Redux no pretende ser la forma más corta de escribir código, sino hacerlo predecible y comprensible". Parte de esto consiste en tener un patrón consistente (las actualizaciones del estado se realizan mediante reductores, así que siempre puedes consultar la lógica del reductor para ver qué valores puede tener el estado, cuáles son las acciones posibles y qué actualizaciones provocan). También se trata de sacar la lógica fuera del árbol de componentes, para que la UI principalmente indique "esto ha sucedido", y tus componentes sean más simples. Además, el código escrito como "funciones puras", como reductores y selectores, es más fácil de entender: argumentos entran, resultado sale, nada más que revisar. Finalmente, el diseño de Redux permitió las Redux DevTools, que muestran una lista legible de todas las acciones despachadas, qué contenían las acciones/estado, y los cambios ocurridos en cada acción.
Los primeros patrones de Redux eran especialmente verbosos. Era común tener actions/todos.js, reducers/todos.js y constants/todos.js, solo para definir un único tipo de acción (const ADD_TODO = "ADD_TODO"), una función creadora de acciones y un caso en el reductor. También había que escribir manualmente actualizaciones inmutables con operadores de propagación, que eran fáciles de estropear. La gente sí que obtenía y almacenaba en caché el estado del servidor en Redux, pero requería mucho código escrito a mano: thunks para realizar la obtención, despachar acciones con los datos obtenidos y gestionar el estado de la caché en los reductores.
Redux se hizo popular a pesar de esa verbosidad, pero siempre fue el principal punto de preocupación.
2017: Competencia en el ecosistema
Hacia 2017-18, las cosas habían cambiado. Gran parte de la comunidad se centraba más en la "obtención y caché de datos" que en la "gestión del estado del lado del cliente", y fue entonces cuando surgieron bibliotecas como Apollo, React Query, SWR y Urql para la obtención de datos. Al mismo tiempo, salió la nueva API de Context de React, que sí transmite correctamente los valores actualizados por el árbol de componentes.
Esto significó que Redux dejó de ser tan "imprescindible" como antes: ahora había otras herramientas que resolvían muchos de los mismos problemas, con distintos grados de solapamiento (y a menudo con menos código). Las quejas frecuentes sobre la "verbosidad" también generaron preocupación entre quienes usaban Redux.
2019: Redux Toolkit
Así que en 2019, creamos y lanzamos Redux Toolkit como una forma más sencilla de escribir la misma lógica de Redux con menos código. RTK sigue siendo "Redux" (almacén único, despachar acciones para activar actualizaciones de estado realizadas en reductores mediante lógica de actualización inmutable), pero con una API más simple y mejores comportamientos predeterminados integrados. Esto incluye RTK Query, nuestra biblioteca integrada para obtención y caché de datos, inspirada en React Query y Apollo.
Hoy, RTK es la forma estándar de escribir lógica de Redux. Como todas las herramientas, tiene compensaciones. RTK probablemente requerirá un poco más de código que Zustand, pero también proporciona patrones útiles para separar la lógica de la aplicación de la UI. Redux no es la herramienta adecuada para todas las aplicaciones, pero sigue siendo la biblioteca de gestión de estado más utilizada en apps de React, tiene una documentación excelente y ofrece muchas características para ayudarte a construir aplicaciones con una estructura consistente y predecible.
Más información
-
Por qué React Context no es una herramienta de "gestión de estado" (y por qué no reemplaza a Redux)
-
Notas arqueológicas y de diseño de Redux (con enlaces a discusiones iniciales de diseño y descripciones de los objetivos del proyecto)