Ir al contenido principal
Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Antecedentes

Redux tiene una herencia mixta. Comparte similitudes con algunos patrones y tecnologías, pero también se diferencia de ellos en aspectos importantes. A continuación exploraremos algunas de estas similitudes y diferencias.

Experiencia para Desarrolladores

Dan Abramov (creador de Redux) desarrolló Redux mientras preparaba su charla para React Europe titulada "Hot Reloading con Viaje en el Tiempo". Su objetivo era crear una biblioteca de gestión de estado con una API mínima pero con comportamiento completamente predecible. Redux permite implementar registro de eventos, hot reloading, viaje en el tiempo, aplicaciones universales, y funciones de grabación y reproducción sin requerir esfuerzo adicional del desarrollador.

Dan habló sobre su enfoque e intenciones en el episodio 187 de Changelog.

Influencias

Redux evoluciona las ideas de Flux, pero evita su complejidad tomando ideas de Elm. Incluso si no has usado Flux o Elm, comenzar con Redux toma solo unos minutos.

Flux

Redux se inspiró en varias cualidades importantes de Flux. Al igual que Flux, Redux propone concentrar la lógica de actualización del modelo en una capa específica de tu aplicación ("stores" en Flux, "reducers" en Redux). En lugar de permitir que el código de la aplicación modifique directamente los datos, ambos exigen describir cada mutación como un objeto simple llamado "acción".

A diferencia de Flux, Redux no incluye el concepto de Dispatcher. Esto se debe a que se basa en funciones puras en lugar de emisores de eventos, y las funciones puras son fáciles de componer sin necesitar una entidad adicional que las gestione. Dependiendo de cómo interpretes Flux, esto podría verse como una desviación o un detalle de implementación. Flux a menudo se ha descrito como (state, action) => state. En este sentido, Redux es fiel a la arquitectura Flux, pero la simplifica gracias al uso de funciones puras.

Otra diferencia importante respecto a Flux es que Redux asume que nunca mutas tus datos. Puedes usar objetos y arrays simples para tu estado, pero se desaconseja encarecidamente mutarlos dentro de los reducers. Siempre debes devolver un nuevo objeto, lo cual puede lograrse usando el operador de propagación de objetos o la biblioteca de actualización inmutable Immer.

Si bien técnicamente es posible escribir reducers impuros que muten datos para casos extremos de rendimiento, desaconsejamos activamente esta práctica. Funciones de desarrollo como viaje en el tiempo, grabación/reproducción o hot reloading dejarán de funcionar. Además, la inmutabilidad no parece causar problemas de rendimiento en la mayoría de aplicaciones reales, porque, como demuestra Om, incluso si pierdes en asignación de objetos, ganas evitando re-renderizados costosos y recálculos, ya que sabes exactamente qué cambió gracias a la pureza de los reducers.

Por si sirve de algo, los creadores de Flux aprueban Redux.

Elm

Elm es un lenguaje de programación funcional inspirado en Haskell y creado por Evan Czaplicki. Impone una arquitectura "modelo-vista-actualización", donde la actualización tiene la siguiente firma: (action, state) => state. Los "actualizadores" de Elm cumplen el mismo propósito que los reducers en Redux.

A diferencia de Redux, Elm es un lenguaje de programación, por lo que puede beneficiarse de características como la pureza forzada, tipado estático, inmutabilidad integrada y coincidencia de patrones (usando la expresión case). Incluso si no planeas usar Elm, deberías leer sobre su arquitectura y experimentar con ella. Existe un interesante playground de biblioteca JavaScript que implementa ideas similares. ¡Podemos buscar allí inspiración para Redux! Una forma de acercarnos al tipado estático de Elm es usando soluciones de tipado gradual como Flow.

Immutable

Immutable es una biblioteca JavaScript que implementa estructuras de datos persistentes. Tiene buen rendimiento y una API idiomática para JavaScript.

(Nota: aunque Immutable.js ayudó a inspirar Redux, hoy recomendamos usar Immer para actualizaciones inmutables).

A Redux no le importa cómo almacenes el estado—puede ser un objeto plano, un objeto Immutable o cualquier otra cosa. Probablemente querrás un mecanismo de (des)serialización para crear aplicaciones universales e hidratar su estado desde el servidor, pero aparte de eso, puedes usar cualquier biblioteca de almacenamiento siempre que admita inmutabilidad. Por ejemplo, no tiene sentido usar Backbone para el estado de Redux porque sus modelos son mutables.

Ten en cuenta que, incluso si tu biblioteca inmutable admite cursores, no deberías usarlos en una aplicación Redux. Todo el árbol de estado debe considerarse de solo lectura, y debes usar Redux para actualizarlo y suscribirte a los cambios. Por lo tanto, escribir mediante cursores no tiene sentido en Redux. Si tu único caso de uso para cursores es desacoplar el árbol de estado del árbol de UI y refinar gradualmente los cursores, deberías considerar usar selectores. Los selectores son funciones getter componibles. Consulta reselect para ver una implementación excelente y concisa de selectores componibles.

Baobab

Baobab es otra biblioteca popular que implementa una API inmutable para actualizar objetos JavaScript planos. Aunque puedes usarla con Redux, hay poco beneficio en combinarlas.

La mayor parte de la funcionalidad de Baobab se relaciona con actualizar datos mediante cursores, pero Redux exige que la única forma de actualizar datos sea despachar acciones. Por lo tanto, resuelven el mismo problema de formas diferentes y no se complementan.

A diferencia de Immutable, Baobab no implementa estructuras de datos eficientes especiales, así que no ganas nada usándolo con Redux. En este caso, es más fácil usar objetos planos.

RxJS

RxJS es una forma excelente de gestionar la complejidad de aplicaciones asíncronas. De hecho, existe un esfuerzo para crear una biblioteca que modele la interacción humano-computadora como observables interdependientes.

¿Tiene sentido usar Redux con RxJS? ¡Claro! Funcionan muy bien juntos. Por ejemplo, es fácil exponer un store de Redux como un observable:

function toObservable(store) {
return {
subscribe({ next }) {
const unsubscribe = store.subscribe(() => next(store.getState()))
next(store.getState())
return { unsubscribe }
}
}
}

De manera similar, puedes componer diferentes flujos asíncronos para convertirlos en acciones antes de pasarlos a store.dispatch().

La pregunta es: ¿realmente necesitas Redux si ya usas Rx? Quizás no. No es difícil reimplementar Redux en Rx. Algunos dicen que son solo dos líneas usando el método .scan() de Rx. ¡Puede ser perfectamente cierto!

Si tienes dudas, revisa el código fuente de Redux (no hay mucho allí) y su ecosistema (por ejemplo, las herramientas de desarrollo). Si no te importa demasiado y prefieres un flujo de datos reactivo completo, quizás quieras explorar algo como Cycle o incluso combinarlo con Redux. ¡Cuéntanos cómo te va!

Testimonios

“Me encanta lo que estás haciendo con Redux” Jing Chen, creadora de Flux

“Pregunté por opiniones sobre Redux en el grupo interno de JS de Facebook y fue elogiado universalmente. Un trabajo realmente increíble.” Bill Fisher, autor de la documentación de Flux

“Es genial que estés inventando un Flux mejor al no hacer Flux en absoluto.” André Staltz, creador de Cycle

Agradecimientos

  • The Elm Architecture por su magnífica introducción a la actualización de estado con reductores;

  • Turning the database inside-out por volarme la cabeza;

  • Developing ClojureScript with Figwheel por convencerme de que la reevaluación debería "simplemente funcionar";

  • Webpack por la Recarga de Módulos en Caliente;

  • Flummox por enseñarme a abordar Flux sin plantillas repetitivas ni singletons;

  • disto por demostrar que los Stores recargables en caliente son posibles;

  • NuclearJS por probar que esta arquitectura puede ser eficiente;

  • Om por popularizar el concepto de un único átomo de estado;

  • Cycle por mostrar que a menudo una función es la mejor herramienta;

  • React por su innovación pragmática.

Agradecimiento especial a Jamie Paton por ceder el nombre del paquete NPM redux.

Patrocinadores

El trabajo original en Redux fue financiado por la comunidad.
Estas son algunas destacadas empresas que lo hicieron posible:

Consulta la lista completa de patrocinadores originales de Redux, así como la creciente lista de personas y empresas que usan Redux.