javascript - react - ¿Por qué usar Redux sobre Facebook Flux?
reactjs and flux (8)
He leído esta respuesta , reduciendo el repetitivo , miré algunos ejemplos de GitHub e incluso probé redux un poco (aplicaciones todo).
Según tengo entendido, las motivaciones oficiales de redux doc proporcionan profesionales en comparación con las arquitecturas MVC tradicionales. PERO no proporciona una respuesta a la pregunta:
¿Por qué deberías usar Redux sobre Facebook Flux?
¿Es solo una cuestión de estilos de programación: funcional versus no funcional? ¿O la pregunta está en las habilidades / herramientas de desarrollo que se derivan del enfoque redux? Tal vez escalar? O prueba?
¿Tengo razón si digo que redux es un flujo para las personas que provienen de lenguajes funcionales?
Para responder a esta pregunta, puede comparar la complejidad de la implementación de los puntos de motivación de redux en flujo frente a redux.
Estos son los puntos de motivación de las motivaciones oficiales de redux doc :
- Manejo de actualizaciones optimistas ( según tengo entendido, apenas depende del quinto punto. ¿Es difícil implementarlo en Facebook Flux? )
- Renderizado en el servidor ( Facebook Flux también puede hacer esto. ¿Hay algún beneficio en comparación con Redux? )
- Obtención de datos antes de realizar transiciones de ruta ( ¿Por qué no se puede lograr en Facebook Flux? ¿Cuáles son los beneficios? )
- Recarga en caliente ( es posible con React Hot Reload . ¿Por qué necesitamos redux? )
- Funcionalidad Deshacer / Rehacer
- ¿Algún otro punto? Como estado persistente ...
¡Autor de Redux aquí!
Redux no es tan diferente de Flux. En general, tiene la misma arquitectura, pero Redux puede reducir algunas esquinas complejas mediante el uso de una composición funcional donde Flux utiliza el registro de devolución de llamada.
No hay una diferencia fundamental en Redux, pero creo que hace que ciertas abstracciones sean más fáciles, o al menos posibles de implementar, que serían difíciles o imposibles de implementar en Flux.
Composición reductora
Tomemos, por ejemplo, la paginación. El ejemplo de My Flux + React Router maneja la paginación, pero el código para eso es horrible. Una de las razones por las que es horrible es que Flux hace que no sea natural reutilizar la funcionalidad en todas las tiendas. Si dos tiendas necesitan manejar la paginación en respuesta a diferentes acciones, o bien deben heredar de una tienda base común (¡mal! Estás encerrándote en un diseño particular cuando usas la herencia), o llamar a una función definida externamente desde el controlador de eventos, que de alguna manera deberá operar en el estado privado de la tienda Flux. Todo es desordenado (aunque definitivamente en el ámbito de lo posible).
Por otro lado, con Redux la paginación es natural gracias a la composición reductora. Son reductores hasta el fondo, por lo que puede escribir una fábrica de reductores que genere reductores de paginación y luego usarlos en su árbol reductor . La clave de por qué es tan fácil es porque en Flux, las tiendas son planas, pero en Redux, los reductores pueden anidarse mediante una composición funcional, al igual que los componentes React pueden anidarse.
Este patrón también permite características maravillosas como undo/redo sin código de usuario. ¿Te imaginas conectar Undo / Redo en una aplicación Flux con dos líneas de código? Apenas. Con Redux, es , de nuevo, gracias al patrón de composición reductor. Debo resaltar que no hay nada nuevo al respecto: este es el patrón pionero y descrito en detalle en Elm Architecture, que fue influenciado por Flux.
Representación del servidor
La gente ha estado renderizando bien en el servidor con Flux, pero al ver que tenemos 20 bibliotecas de Flux que intentan hacer que la representación del servidor sea "más fácil", quizás Flux tiene algunas asperezas en el servidor. La verdad es que Facebook no hace mucha representación del servidor, por lo que no se han preocupado mucho por eso y confían en el ecosistema para hacerlo más fácil.
En Flux tradicional, las tiendas son singletons. Esto significa que es difícil separar los datos para diferentes solicitudes en el servidor. No imposible, pero difícil. Esta es la razón por la cual la mayoría de las bibliotecas de Flux (así como las nuevas Flux Utils ) ahora sugieren que use clases en lugar de singletons, para que pueda crear instancias de tiendas por solicitud.
Todavía existen los siguientes problemas que debe resolver en Flux (usted mismo o con la ayuda de su biblioteca de Flux favorita, como Flummox o Alt ):
- Si las tiendas son clases, ¿cómo las creo y las destruyo con el despachador por solicitud? ¿Cuándo registro tiendas?
- ¿Cómo hidrato los datos de las tiendas y luego los rehidrato en el cliente? ¿Necesito implementar métodos especiales para esto?
Es cierto que los frameworks Flux (no vanilla Flux) tienen soluciones a estos problemas, pero los encuentro demasiado complicados.
Por ejemplo,
Flummox le pide que implemente
serialize()
y
deserialize()
en sus tiendas
.
Alt resuelve esto mejor al proporcionar
takeSnapshot()
que serializa automáticamente su estado en un árbol JSON.
Redux va más allá: dado que hay una sola tienda (administrada por muchos reductores), no necesita ninguna API especial para administrar la (re) hidratación. No es necesario "vaciar" o "hidratar" las tiendas: hay una sola tienda y puede leer su estado actual o crear una nueva tienda con un nuevo estado. Cada solicitud obtiene una instancia de tienda separada. Lea más sobre la representación del servidor con Redux.
De nuevo, este es un caso de algo posible tanto en Flux como en Redux, pero las bibliotecas de Flux resuelven este problema introduciendo un montón de API y convenciones, y Redux ni siquiera tiene que resolverlo porque no tiene ese problema en el primer lugar gracias a la simplicidad conceptual.
Experiencia de desarrollador
En realidad, no tenía la intención de que Redux se convirtiera en una biblioteca popular de Flux; la escribí mientras trabajaba en mi charla de ReactEurope sobre recarga en caliente con viajes en el tiempo . Tenía un objetivo principal: hacer posible cambiar el código reductor sobre la marcha o incluso "cambiar el pasado" tachando acciones y ver cómo se recalcula el estado.
No he visto una sola biblioteca de Flux que pueda hacer esto. React Hot Loader tampoco le permite hacer esto; de hecho, se rompe si edita las tiendas Flux porque no sabe qué hacer con ellas.
Cuando Redux necesita volver a cargar el código reductor, llama a
replaceReducer()
y la aplicación se ejecuta con el nuevo código.
En Flux, los datos y las funciones están enredados en las tiendas de Flux, por lo que no puede "simplemente reemplazar las funciones".
Además, tendría que volver a registrar de alguna manera las nuevas versiones con Dispatcher, algo que Redux ni siquiera tiene.
Ecosistema
Redux tiene un ecosistema rico y de rápido crecimiento . Esto se debe a que proporciona algunos puntos de extensión, como middleware . Fue diseñado con casos de uso como logging , soporte para Promises , Observables , routing , comprobaciones de desarrollo de inmutabilidad , persistence , etc., en mente. No todos estos resultarán útiles, pero es bueno tener acceso a un conjunto de herramientas que se pueden combinar fácilmente para trabajar juntos.
Sencillez
Redux conserva todos los beneficios de Flux (grabación y reproducción de acciones, flujo de datos unidireccional, mutaciones dependientes) y agrega nuevos beneficios (fácil deshacer, rehacer, recarga en caliente) sin introducir Dispatcher y registrar la tienda.
Mantenerlo simple es importante porque te mantiene cuerdo mientras implementas abstracciones de alto nivel.
A diferencia de la mayoría de las bibliotecas de Flux, la superficie API de Redux es pequeña. Si elimina las advertencias, comentarios y comprobaciones de cordura del desarrollador, son 99 líneas . No hay código asincrónico complicado para depurar.
De hecho, puede leerlo y comprender todo Redux.
Vea también mi respuesta sobre las desventajas de usar Redux en comparación con Flux .
Aquí está la explicación simple de Redux sobre Flux. Redux no tiene un despachador. Se basa en funciones puras llamadas reductores. No necesita un despachador. Cada acción es manejada por uno o más reductores para actualizar la tienda individual. Como los datos son inmutables, los reductores devuelven un nuevo estado actualizado que actualiza la tienda
Para más información Flux vs Redux
De acuerdo con este artículo: https://medium.freecodecamp.org/a-realworld-comparison-of-front-end-frameworks-with-benchmarks-2019-update-4be0d3c78075
Es mejor que use MobX para administrar los datos en su aplicación para obtener un mejor rendimiento, no Redux.
De un nuevo adoptante react / redux que migra desde (algunos años de) ExtJS a mediados de 2018:
Después de deslizarme hacia atrás por la curva de aprendizaje redux, tuve la misma pregunta y pensé que el flujo puro sería más simple como OP.
Pronto vi los beneficios de redux sobre flux como se señala en las respuestas anteriores, y estaba trabajando en mi primera aplicación.
Mientras volvía a controlar la placa de la caldera, probé algunas de las otras bibliotecas de gestión estatal, lo mejor que encontré fue la rematch .
Fue mucho más intuitivo que Vanilla Redux, cortó el 90% de la repetitiva y recortó el 75% del tiempo que estaba gastando en Redux (algo que creo que una biblioteca debería estar haciendo), pude obtener un par de aplicaciones empresariales ir de inmediato
También funciona con las mismas herramientas redux. Este es un buen artículo que cubre algunos de los beneficios.
Por lo tanto, para cualquier persona que haya llegado a esta publicación SO buscando "redux más simple", recomiendo probarlo como una alternativa simple a redux con todos los beneficios y 1/4 de la repetitiva.
Puede que sea mejor comenzar con la lectura de esta publicación de Dan Abramov donde analiza varias implementaciones de Flux y sus compensaciones en el momento en que estaba escribiendo redux: The Evolution of Flux Frameworks
En segundo lugar, esa página de motivaciones a la que se vincula realmente no discute las motivaciones de Redux tanto como las motivaciones detrás de Flux (y React). Los Tres Principios son más específicos de Redux, aunque aún no abordan las diferencias de implementación de la arquitectura estándar de Flux.
Básicamente, Flux tiene múltiples tiendas que calculan el cambio de estado en respuesta a las interacciones UI / API con los componentes y difunden estos cambios como eventos a los que los componentes pueden suscribirse. En Redux, solo hay una tienda a la que se suscribe cada componente. En mi opinión, al menos parece que Redux simplifica y unifica aún más el flujo de datos al unificar (o reducir, como diría Redux) el flujo de datos de regreso a los componentes, mientras que Flux se concentra en unificar el otro lado del flujo de datos. modelo.
Soy uno de los primeros en adoptar e implementé una aplicación de página única de tamaño medio grande usando la biblioteca Facebook Flux.
Como llego un poco tarde a la conversación, solo señalaré que, a pesar de mis mejores esperanzas, Facebook parece considerar que su implementación de Flux es una prueba de concepto y nunca ha recibido la atención que merece.
Te animo a que juegues con él, ya que expone más del funcionamiento interno de la arquitectura Flux, que es bastante educativo, pero al mismo tiempo no proporciona muchos de los beneficios que brindan bibliotecas como Redux (que no son eso es importante para proyectos pequeños, pero se vuelve muy valioso para proyectos más grandes).
Hemos decidido que en el futuro nos trasladaremos a Redux y le sugiero que haga lo mismo;)
Trabajé mucho tiempo con Flux y ahora mucho tiempo con Redux. Como Dan señaló, ambas arquitecturas no son tan diferentes. La cuestión es que Redux hace las cosas más simples y limpias. Te enseña un par de cosas además de Flux. Como por ejemplo, Flux es un ejemplo perfecto del flujo de datos en una dirección. Separación de preocupaciones donde tenemos datos, sus manipulaciones y la capa de vista separada. En Redux tenemos las mismas cosas, pero también aprendemos sobre la inmutabilidad y las funciones puras.
En primer lugar, es totalmente posible escribir aplicaciones con React sin Flux.
También este diagrama visual que he creado para mostrar una vista rápida de ambos, probablemente una respuesta rápida para las personas que no quieren leer la explicación completa:
Pero si todavía te interesa saber más, sigue leyendo.
Creo que deberías comenzar con React puro, luego aprender Redux y Flux. Después de tener una experiencia REAL con React, verá si Redux es útil para usted o no.
Tal vez sienta que Redux es exactamente para su aplicación y tal vez descubra que Redux está tratando de resolver un problema que realmente no está experimentando.
Si comienza directamente con Redux, puede terminar con un código sobredimensionado, un código más difícil de mantener y con aún más errores y sin Redux.
De los documentos de Redux :
Motivación
Como los requisitos para las aplicaciones JavaScript de una sola página se han vuelto cada vez más complicados, nuestro código debe administrar más estado que nunca. Este estado puede incluir respuestas del servidor y datos en caché, así como datos creados localmente que aún no se han conservado en el servidor. El estado de la IU también está aumentando en complejidad, ya que necesitamos administrar rutas activas, pestañas seleccionadas, hilanderos, controles de paginación, etc.Gestionar este estado siempre cambiante es difícil. Si un modelo puede actualizar otro modelo, entonces una vista puede actualizar un modelo, que actualiza otro modelo, y esto, a su vez, puede hacer que se actualice otra vista. En algún momento, ya no comprende lo que sucede en su aplicación, ya que ha perdido el control sobre cuándo, por qué y cómo su estado. Cuando un sistema es opaco y no determinista, es difícil reproducir errores o agregar nuevas características.
Como si esto no fuera lo suficientemente malo, considere que los nuevos requisitos se vuelven comunes en el desarrollo de productos front-end. Como desarrolladores, se espera que manejemos las actualizaciones optimistas, la representación del lado del servidor, la obtención de datos antes de realizar las transiciones de ruta, etc. Nos encontramos tratando de manejar una complejidad con la que nunca hemos tenido que lidiar antes, e inevitablemente hacemos la pregunta: ¿Es hora de rendirnos? La respuesta es no.
Esta complejidad es difícil de manejar ya que estamos mezclando dos conceptos que son muy difíciles de razonar para la mente humana: la mutación y la asincronía. Los llamo Mentos y Coca-Cola. Ambos pueden ser geniales cuando se separan, pero juntos crean un desastre. Las bibliotecas como React intentan resolver este problema en la capa de vista eliminando tanto la asincronía como la manipulación directa del DOM. Sin embargo, administrar el estado de sus datos depende de usted. Aquí es donde entra Redux.
Siguiendo los pasos de Flux, CQRS y Event Sourcing, Redux intenta hacer que las mutaciones de estado sean predecibles imponiendo ciertas restricciones sobre cómo y cuándo pueden ocurrir actualizaciones. Estas restricciones se reflejan en los tres principios de Redux.
También de los documentos de Redux :
Conceptos básicos
Redux en sí es muy simple.Imagina que el estado de tu aplicación se describe como un objeto simple. Por ejemplo, el estado de una aplicación de tareas puede verse así:
{ todos: [{ text: ''Eat food'', completed: true }, { text: ''Exercise'', completed: false }], visibilityFilter: ''SHOW_COMPLETED'' }
Este objeto es como un "modelo", excepto que no hay establecedores. Esto es para que diferentes partes del código no puedan cambiar el estado arbitrariamente, causando errores difíciles de reproducir.
Para cambiar algo en el estado, debe enviar una acción. Una acción es un objeto JavaScript simple (¿observa cómo no introducimos ninguna magia?) Que describe lo que sucedió. Aquí hay algunos ejemplos de acciones:
{ type: ''ADD_TODO'', text: ''Go to swimming pool'' } { type: ''TOGGLE_TODO'', index: 1 } { type: ''SET_VISIBILITY_FILTER'', filter: ''SHOW_ALL'' }
Hacer cumplir que cada cambio se describa como una acción nos permite tener una comprensión clara de lo que está sucediendo en la aplicación. Si algo cambió, sabemos por qué cambió. Las acciones son como migas de pan de lo que ha sucedido. Finalmente, para unir el estado y las acciones, escribimos una función llamada reductor. Una vez más, no tiene nada de mágico: es solo una función que toma el estado y la acción como argumentos, y devuelve el siguiente estado de la aplicación. Sería difícil escribir una función de este tipo para una aplicación grande, por lo que escribimos funciones más pequeñas que administran partes del estado:
function visibilityFilter(state = ''SHOW_ALL'', action) { if (action.type === ''SET_VISIBILITY_FILTER'') { return action.filter; } else { return state; } } function todos(state = [], action) { switch (action.type) { case ''ADD_TODO'': return state.concat([{ text: action.text, completed: false }]); case ''TOGGLE_TODO'': return state.map((todo, index) => action.index === index ? { text: todo.text, completed: !todo.completed } : todo ) default: return state; } }
Y escribimos otro reductor que gestiona el estado completo de nuestra aplicación llamando a esos dos reductores para obtener las claves de estado correspondientes:
function todoApp(state = {}, action) { return { todos: todos(state.todos, action), visibilityFilter: visibilityFilter(state.visibilityFilter, action) }; }
Esta es básicamente toda la idea de Redux. Tenga en cuenta que no hemos utilizado ninguna API de Redux. Viene con algunas utilidades para facilitar este patrón, pero la idea principal es que describa cómo su estado se actualiza con el tiempo en respuesta a los objetos de acción, y el 90% del código que escribe es simplemente JavaScript, sin uso de Redux en sí mismo, sus API o cualquier magia.