¿Por qué usar Redux sobre Facebook Flux? [cerrado]

1126

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 :

  1. Manejo de actualizaciones optimistas ( según tengo entendido, apenas depende del quinto punto. ¿Es difícil implementarlo en Facebook Flux? )
  2. Renderizado en el servidor ( Facebook Flux también puede hacer esto. ¿Hay algún beneficio en comparación con Redux? )
  3. Obtención de datos antes de realizar transiciones de ruta ( ¿Por qué no se puede lograr en Facebook Flux? ¿Cuáles son los beneficios? )
  4. Recarga en caliente ( es posible con React Hot Reload . ¿Por qué necesitamos redux? )
  5. Funcionalidad Deshacer / Rehacer
  6. ¿Algún otro punto? Como estado persistente ...
VB_
fuente
73
Redux es una implementación de "Facebook Flux". Flux no es una biblioteca o marco. Es simplemente una arquitectura recomendada para aplicaciones web. No veo cómo se puede comparar una implementación concreta con el concepto abstracto que lo motivó. La implementación real de Facebook de una arquitectura Flux es Relay y la versión de código abierto aún se encuentra en las primeras etapas. facebook.github.io/relay
Charlie Martin
2
@CharlieMartin Por FB Flux I me aplicación como esta github.com/facebook/flux/tree/master/examples . Mi proyecto actual está escrito en FB Flux (debido a FB Flux). Si lo desea, puede pensar como arquitectura Redux sobre arquitectura FB Flux.
VB_
2
Entiendo ahora. Desea comparar la implementación Flux de ejemplo de Facebook con la implementación Flux de Redux
Charlie Martin
13
Relay no es una implementación de Flux: Relay / GraphQL está más preocupado por la gestión de búsqueda / consulta de datos con el servidor, mientras que Flux se preocupa principalmente por estructurar el flujo de datos entre los modelos de datos del lado del cliente y los componentes de vista. Sin embargo, existe cierta superposición: en Facebook, tenemos aplicaciones creadas completamente con Flux, completamente con Relay o con ambas. Un patrón que vemos emergente es dejar que Relay administre la mayor parte del flujo de datos para una aplicación, pero usar los almacenes Flux en el lateral para manejar un subconjunto del estado de la aplicación
Hal

Respuestas:

1958

¡Autor de Redux aquí!

Redux no es que diferente de Flujo. 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 deshacer / rehacer 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. Tengo que 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 el procesamiento del servidor sea "más fácil", quizás Flux tenga algunas asperezas en el servidor. La verdad es que Facebook no hace mucha representación del servidor, por lo que no se han preocupado demasiado 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 hay 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 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 registro , soporte para Promesas , Observables , enrutamiento , comprobaciones de desarrollo de inmutabilidad , persistencia , 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 .

Dan Abramov
fuente
3
gracias por la respuesta ... Soy nuevo en js..en su respuesta usted dijo que flux está usando un patrón de diseño único ... ¿puede decirme en redux qué tipo de patrón de diseño están usando ... y en flux can me dices dónde están usando el patrón singleton ... ¿puedes dar un ejemplo? Entiendo lo que hace el patrón de diseño desde aquí singleton
2
Comencé mi implementación de Android / Java (Fluxxan) basada en Fluxxor (básicamente flujo puro). Una vez que vi redux, me vendieron. Hay algunas porciones que mantuve puramente cambiantes, pero hombre, ¡tu lib es increíble!
frostymarvelous
55
¿Quieres aprender Redux? solo mira este
video
55
Elegimos que ser redux sea mucho más obstinado que flux. Estábamos constantemente peleando sobre cómo / dónde debía ir cierto código, etc. Redux eliminó toda esa confusión para nosotros. ¡Hemos creado aplicaciones con redux para web y react-native y es increíble!
SomethingOn
1
La línea github.com/reactjs/redux/blob/… fue la respuesta a la pregunta que estaba buscando durante una semana: cómo estructurar la tienda y los reductores, para que se puedan manejar múltiples instancias de componentes reutilizables utilizados en diferentes contextos sin duplicar lógica. La respuesta parece ser: usar tres niveles de almacenamiento profundo: 1er nivel: nombre del componente ("paginación"), 2do nivel: nombre del contenedor ("stargazersByRepo"), 3 niveles: la clave / id única del contenedor ( ${login}/${name}) ¡Muchas gracias!
qbolec
101

En Quora, alguien dice :

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: Flux vs Redux

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 está 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: mutación y 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í mismo 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 podría 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 describa 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.

Alireza
fuente
57

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.

Hal
fuente
27

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;)

Guy Nesher
fuente
He estado desarrollando la aplicación Facebook Flux durante seis meses. Y todavía no estoy seguro si un tiempo de migración vale los beneficios que proporciona Redux. ¡Apreciaré mucho todos sus comentarios sobre los pros / contras de Redux sobre FB flux!
VB_
1
@VolodymyrBakhmatiuk para nosotros se trata principalmente de reducir la cantidad de repeticiones que tenemos que escribir + un mejor manejo de errores (redux, por ejemplo, gritará si dispara una acción que no se definió en su lista constante; el flujo de FB no lo hará y puede causar todo tipo de problemas) Hay algunas capacidades más avanzadas en flujo, pero aún no las he usado
Guy Nesher
1
@GuyNesher se debe detectar una acción indefinida en tiempo de compilación, no en tiempo de ejecución. Flow (otra contribución de Facebook) te permite hacer eso.
Dominique PERETTI
@DominiquePERETTI: cierto (también se puede usar linting) pero no cambia el hecho de que no detectar el error en el tiempo de ejecución es un poco triste
Guy Nesher
Escribí algunos simples ayudantes para tratar con FBFlux, y en realidad parece ser menos repetitivo y la configuración de la aplicación que todas las aplicaciones de Redux de ejemplo que he encontrado. Trabajé en una aplicación durante más de 9 meses entre dos desarrolladores y nunca tuve ningún problema con la arquitectura.
rob2d
20

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 tiendaingrese la descripción de la imagen aquí

Para más información Flux vs Redux

Prathap Kudupu
fuente
Acerca de varias tiendas, ahora es algo factible en Redux, en react-redux puede agregar una clave para aislar tiendas: redux.js.org/faq/storesetup muestra de trabajo: github.com/Lemoncode/redux-multiple-stores
Braulio
6

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.

Krasimir
fuente
5

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 administración estatal, lo mejor que encontré fue la revancha .

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 debería estar haciendo una biblioteca), 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.

vanderwyst
fuente