Redux y RxJS, ¿alguna similitud?

113

Sé que Redux es una mejor "implementación" de Flux, o mejor dicho, es un rediseño para simplificar las cosas (administración del estado de la aplicación).

He escuchado mucho sobre la programación reactiva (RxJS), pero aún no me he sumergido para aprenderlo.

Entonces mi pregunta es: ¿hay alguna intersección (algo en común) entre estas dos tecnologías o son complementarias? ... o totalmente diferente?

Oswaldo
fuente

Respuestas:

185

En resumen, son bibliotecas muy diferentes para propósitos muy diferentes, pero sí hay algunas similitudes vagas.

Redux es una herramienta para administrar el estado en toda la aplicación. Por lo general, se usa como arquitectura para interfaces de usuario. Piense en ello como una alternativa a (la mitad de) Angular.

RxJS es una biblioteca de programación reactiva. Suele utilizarse como herramienta para realizar tareas asincrónicas en JavaScript. Piense en ello como una alternativa a Promesas.


La programación reactiva es un paradigma (forma de trabajar y pensar) donde los cambios en los datos se observan a distancia . Los datos no se cambian a distancia .

Aquí hay un ejemplo de cambio a distancia :

// In the controller.js file
model.set('name', 'George');

El modelo se cambia del controlador.

Aquí hay un ejemplo de observado desde la distancia :

// logger.js
store.subscribe(function (data) {
    console.log(data);
});

En el Logger, observamos los cambios de datos que ocurren en Store (desde la distancia) y escribimos en la consola.


Redux usa el paradigma reactivo solo un poco: la tienda es reactiva. No configuras su contenido a distancia. Por eso no hay store.set()en Redux. La Tienda observa las acciones a distancia y se cambia a sí misma. Y la Tienda permite que otros observen sus datos a distancia.

RxJS también usa el paradigma reactivo, pero en lugar de ser una arquitectura, le brinda bloques de construcción básicos, Observables , para lograr este patrón de "observación desde la distancia".

Para concluir, cosas muy diferentes para diferentes propósitos, pero comparta algunas ideas.

André Staltz
fuente
4
No, no deberías usarlos juntos. La gente ha emulado a Redux usando Rx. Un Google rápido encontrará ejemplos para usted. Si desea utilizar Rx para su interfaz de usuario reactiva, consulte Cycle.js, el marco de Andre. Lo he estado usando últimamente y es fantástico. La API ha cambiado mucho recientemente, pero creo que finalmente está comenzando a congelar partes de ella.
Joel Dentici
17
según los documentos oficiales de redux , "Funcionan muy bien juntos".
galki
12
¡Funcionan muy bien juntos! Existe un middleware de Redux que le brinda la oportunidad de usar RxJS y Observables para acciones de Redux. github.com/redux-observable/redux-observable Además, escribí una publicación de blog sobre cómo: robinwieruch.de/redux-observable-rxjs
Robin Wieruch
1
El paradigma de Redux ayudó a que la base de código de mi proyecto de Android fuera más reactiva. Nuestros flujos de datos provenientes de botones y otros campos para actualizar un estado, junto con RxJava, sobrealimentaron nuestra legibilidad y rendimiento. Las bibliotecas definitivamente van bien juntas y sus beneficios son independientes del idioma.
Kenny Worden
Funcionan muy bien juntos, pero en la práctica, Reactive puede hacer por usted lo que haría Redux: sincronizar el estado de sus componentes con el modelo, por lo que a menudo no tiene mucho sentido usar ambos
Filip Sobczak
32

Son cosas muy distintas.

RxJS se puede utilizar para realizar programación reactiva y es una biblioteca muy completa con más de 250 operadores.

Y Redux es como se describe en el repositorio de github "Redux es un contenedor de estado predecible para aplicaciones JavaScript".

Redux es solo una herramienta para manejar el estado de las aplicaciones. Pero en comparación, podría crear una aplicación completa en solo RxJS.

Espero que esto ayude :)

cmdv
fuente
3
Tu respuesta también es buena @cmdv. No lo vi cuando escribía el mío.
André Staltz
4

Redux es una biblioteca de administración estatal que viene con estándares bien definidos para operaciones de actualización. En la medida en que cumpla con los estándares, puede mantener el flujo de datos sano y fácil de razonar. También brinda la capacidad de mejorar el flujo de datos con middlewares y optimizadores de tienda.

RxJS es un juego de herramientas para programación reactiva. De hecho, puede pensar en todo lo que sucede en su aplicación como una transmisión. RxJS ofrece un conjunto de herramientas muy completo para administrar esos flujos.

¿Dónde intercepta RxJS y Redux? En redux, actualiza su estado con acciones y, obviamente, estas acciones pueden tratarse como corrientes. Usando un middleware como redux-observable (no es necesario) puede implementar su llamada "lógica de negocios" de una manera reactiva. Otra cosa es que puede crear un observable desde su tienda redux que a veces puede ser más fácil que usar un potenciador.

mdikici
fuente
2

Para resumir:

Redux: Biblioteca inspirada en Flux utilizada para State Management .

RxJS: Es otra biblioteca de Javascript basada en la filosofía de programación reactiva, utilizada para tratar con "Streams" (Observables, etc.) [Leer sobre Programación Reactiva para entender los conceptos de Stream].

Krishna Ganeriwal
fuente
1

Solo quería agregar algunas diferencias pragmáticas de cuando hice el código RxJS inspirado en Redux.

Mapeé cada tipo de acción a una instancia de Asunto. Cada componente con estado tendrá un Asunto que luego se mapeará en una función reductora. Todas las corrientes de reductor se combinan con el estado mergey luego lo scangeneran. El valor predeterminado se establece startWithjusto antes de scan. Usé publishReplay(1)para estados, pero podría eliminarlo más adelante.

La función de renderizado puro de reacción será solo colocar donde se produzcan datos de eventos enviando a todos los productores / sujetos.

Si tiene componentes secundarios, debe describir cómo se combinan esos estados en el suyo. combineLatestpodría ser un buen punto de partida para eso.

Diferencias notables en la implementación:

  • Sin middleware, solo operadores rxjs. Creo que este es el mayor poder y debilidad. Aún puede tomar prestados conceptos, pero me resulta difícil obtener ayuda de comunidades hermanas como redux y cycle.js, ya que es otra solución personalizada. Por eso necesito escribir "yo" en lugar de "nosotros" en este texto.

  • Sin interruptor / caja o cadenas para tipos de acción. Tienes una forma más dinámica de separar acciones.

  • rxjs se puede utilizar como herramienta en otros lugares y no está incluido en la administración estatal.

  • Menor número de productores que tipos de acción (?). No estoy seguro de esto, pero puede tener muchas reacciones en los componentes principales que escuchan a los componentes secundarios. Eso significa código menos imperativo y menos complejidad.

  • Eres dueño de la solución. No se necesita marco. Bueno y malo. Terminarás escribiendo tu propio marco de todos modos.

  • Es mucho más fractal y puede suscribirse fácilmente a los cambios de un subárbol o de varias partes del árbol de estado de la aplicación.

    • ¿Adivina lo fácil que es hacer epopeyas como redux-obseravble? Realmente fácil.

También estoy trabajando en beneficios mucho mayores donde los componentes secundarios se describen como flujos. Esto significa que no tenemos que completar el estado principal y secundario en los reductores, ya que podemos simplemente ("solo") combinar recursivamente los estados según la estructura del componente.

También pienso en omitir Reaccionar e ir con snabbdom o algo más hasta que React maneje mejor los estados reactivos. ¿Por qué deberíamos construir nuestro estado hacia arriba solo para descomponerlo a través de accesorios nuevamente? Así que intentaré hacer una versión 2 de este patrón con Snabbdom.

Aquí hay un fragmento más avanzado pero pequeño en el que el archivo state.ts crea el flujo de estado. Este es el estado del componente ajax-form que obtiene un objeto de campos (entradas) con reglas de validación y estilos css. En este archivo, solo usamos los nombres de campo (claves de objeto) para combinar todos los estados secundarios en el estado del formulario.

export default function create({
  Observable,
  ajaxInputs
}) {
  const fieldStreams = Object.keys(ajaxInputs)
  .map(function onMap(fieldName) {
    return ajaxInputs[fieldName].state.stream
    .map(function onMap(stateData) {
      return {stateData, fieldName}
    })
  })

  const stateStream = Observable.combineLatest(...fieldStreams)
  .map(function onMap(fieldStreamDataArray) {
    return fieldStreamDataArray.reduce(function onReduce(acc, fieldStreamData) {
    acc[fieldStreamData.fieldName] = fieldStreamData.stateData
    return acc
  }, {})
  })

  return {
    stream: stateStream
  }
}

Si bien es posible que el código no diga mucho de forma aislada, muestra cómo puede construir el estado hacia arriba y cómo puede producir eventos dinámicos con facilidad. El precio a pagar es que debe comprender un estilo de código diferente. Y me encanta pagar ese precio.

Marcus Rådell
fuente
Un año después, encontré tu respuesta y creo que sigue siendo válida. Hice algo similar y estoy de acuerdo con todos tus puntos. Pero una pregunta de todos modos: ¿Sigues pensando lo mismo hoy o has seguido adelante desde entonces?
Xceno
1
Necesito revisar la crítica sobre switch / case y tipos de acción en Redux. Sigo codificando de la misma manera, pero trato de trabajar para que funcione en el lado del servidor. Cuando se trata del código de React, me las arreglé para hacer una pequeña utilidad que ayuda a crear los reductores / actualizadores. Así que sigo haciendo lo mismo, pero un poco más pulido. El cambio más grande es que dejo que cada nodo hoja se suscriba a la secuencia en componentDidMount y me cancele la suscripción en componentDidUnmount. También quiero obtener una capa de servicio reactiva que funcione en el frontend y el backend. Haciendo progresos allí.
Marcus Rådell