Redux: Solicitud de debate: "repetitivo" de Redux, curva de aprendizaje, abstracción y obstinación

Creado en 19 mar. 2017  ·  108Comentarios  ·  Fuente: reduxjs/redux

Resolución: use Redux Starter Kit

Las ideas de este hilo eventualmente se convirtieron en nuestro nuevo paquete Redux Starter Kit . Incluye utilidades para simplificar muchos casos de uso comunes de Redux, incluida la configuración de la tienda, la definición de reductor, la lógica de actualización inmutable e incluso la creación de "cortes" completos de estado automáticamente sin escribir ningún creador de acción o tipo de acción a mano.

Para obtener más detalles sobre los problemas que Redux Starter Kit debe resolver (y lo que no hará), consulte el manifiesto "Visión para Redux Starter Kit" que escribí .

La queja número uno que veo sobre Redux es que hay "demasiada repetición". También veo con frecuencia quejas de que hay mucho que aprender, demasiados complementos que se necesitan para hacer algo útil y demasiados aspectos en los que Redux no tiene ninguna opinión y, por lo tanto, no ofrece ningún tipo de orientación incorporada.

Acabo de tener una discusión con @tannerlinsley sobre varios de estos aspectos. Discutimos la biblioteca Jumpstate , que es una capa de abstracción alrededor de Redux, y cómo se pretendía facilitar la curva de aprendizaje, así como varias opiniones filosóficas sobre lo que constituye el uso "bueno" de Redux.

A partir de eso, se nos ocurrieron varias preguntas que me gustaría plantear para una discusión más amplia:

Puntos clave

Texto estándar / verbosidad

  • Redux no pretende ser la "forma más concisa de hacer las cosas", sino más bien hacer que el flujo de datos sea obvio y legible.
  • Los documentos están escritos en un estilo deliberadamente detallado para mayor claridad y aprendizaje, y no están pensados ​​específicamente como "la única forma verdadera de escribir código Redux", pero ese estilo ha sido adoptado ciegamente (o, a veces, ha resultado en el rechazo de Redux).
  • Quejas frecuentes sobre "texto estándar", como "demasiados archivos", "uso de creadores de acciones", etc.

Abstracciones y aprendizaje

  • La biblioteca central de Redux en sí misma tiene funciones completas, pero la comunidad está construyendo muchos complementos y herramientas interesantes
  • Se han creado varias bibliotecas de abstracción para "facilitar la curva de aprendizaje" o "hacer las cosas más orientadas a objetos", pero la mayoría de ellas no son realmente "idiomáticas" en el uso de Redux
  • La curva de aprendizaje de Redux puede ser empinada, pero una vez que comprende los conceptos, la necesidad de capas de abstracción a menudo desaparece.

Problemas

  • ¿De qué se tratan principalmente las quejas "estándar"?
  • ¿Cuáles son los aspectos más difíciles de Redux para los nuevos estudiantes?
  • ¿Cuáles son las áreas "sin opiniones" que causan problemas a las personas?

Soluciones potenciales

  • ¿Cómo sería el uso idiomático de Redux con "menos repetitivo"? ¿Cómo podemos brindar soluciones a esas quejas?
  • ¿Qué posibles abstracciones podrían crearse que simplifiquen el proceso de aprendizaje y uso, pero sin ocultar realmente Redux (y con suerte proporcionarían una ruta de migración / aprendizaje a Redux "base")?
  • ¿Cuánto de esto podría resolverse con documentos mejorados de alguna manera?

Me gustaría invitar a la comunidad a presentar quejas, puntos débiles e inquietudes sobre el uso de Redux y, con suerte, también brindar sugerencias e ideas para resolver esos problemas.

Comentario más útil

Si fuera por mí, me gustaría ver esto:

  • Un subconjunto compatible con Flow / TypeScript que es más fácil de escribir que Vanilla Redux.
  • No enfatizar tanto las constantes (solo haga que el uso de literales de cadena sea más seguro).
  • Manteniendo la independencia de React u otras bibliotecas de vistas, pero facilitando el uso de enlaces existentes (por ejemplo, proporcionando implementaciones mapStateToProps ).
  • Preservar los principios de Redux (acciones serializables, viajes en el tiempo y recarga en caliente deberían funcionar, el registro de acciones debería tener sentido).
  • Admite la división de código de una manera más sencilla desde el primer momento.
  • Fomentar la colocación de reductores con selectores y hacerlos menos incómodos de escribir juntos (piense en paquetes de reductor-selector que son fáciles de escribir y componer).
  • En lugar de colocar a los creadores de acciones con reductores, deshacerse de los creadores de acciones por completo y hacer que el mapeo de muchos a muchos de acciones a reductores sea natural (en lugar de rehuirlo como lo hacen la mayoría de las bibliotecas).
  • Hacer valores predeterminados de rendimiento razonables para que la memorización a través de Reselect "simplemente funcione" para casos de uso comunes sin que los usuarios escriban ese código.
  • Contiene ayudantes integrados para indexación, normalización, recopilaciones y actualizaciones optimistas.
  • Tener soporte de flujo asíncrono comprobable incorporado.

Además del núcleo, por supuesto, aunque está bien marcarlo como algo oficial de Redux.
Además, no escribiré esto. Pero puedes.

Todos 108 comentarios

Algunas ideas:

  • paquete oficial de redux-preset que contiene redux, react-redux, redux-thunk ya conectados
  • dispatch(actionType, payload) podría reducir la necesidad de creadores de acciones
  • creadores de reductores de estilo jumpstate incorporados, por ejemplo, createReducer({[actionType]: (state, payload) => state}, initState)

La mayoría de las personas que conozco que usan redux en gran medida, terminan alejándose de redux-thunk porque descubren que no escala muy bien y termina conduciendo a creadores de acción que comienzan a hacer demasiado, y prefieren usar otra cosa para administrar el lado -efectos como redux-observable o redux-saga.

Puedo entender el atractivo que tiene, especialmente al comenzar con redux, pero no estoy seguro de si agruparlo como parte de un 'paquete repetitivo de mejores prácticas' sería la mejor idea.

Entonces, esta parte es la más crítica para mí (no serán tanto ideas para resolver el problema, sino restricciones que son, al menos para mí, importantes):

Redux no pretende ser la "forma más concisa de hacer las cosas", sino más bien hacer que el flujo de datos sea obvio y legible.

Una gran cosa acerca de Redux es que es casi más un patrón de diseño que un marco, y todo el código que ves (aparte de la tienda y react-redux ) es tuyo.

Mirando Jumpstate (no lo sabía hasta ahora), es una de las primeras capas de abstracción que veo para Redux que se ve bien. ¡Genial incluso! Pero al mismo tiempo, solo te aleja un pelo de otros marcos como MobX, y tener múltiples marcos que traen lo mismo a la mesa no es muy útil. Por lo tanto, es importante centrarse en lo que hace que Redux sea diferente del resto, no solo en cómo podemos mejorar Redux en el vacío (porque vive en el mismo mundo que otras herramientas).

Otra cosa importante es que muchos de los desafíos que tienen los recién llegados cuando llegan a Redux no es Redux en sí, sino JavaScript. Otros grandes marcos como Angular abstraen el propio JavaScript. Escribir un reductor de Redux es simplemente aplicar "patrones de diseño" de JavaScript vanilla, que pueden no ser familiares para los recién llegados, y hará que la gente quiera usar una caja negra en su lugar.

Finalmente, muchas bibliotecas de reducción estándar intentan agregar una relación 1: 1: 1 entre componentes, reductores y creadores de acciones (tal vez no los 3, pero a menudo 2 de ellos), lo que hace que los recién llegados olviden que pueden tener múltiples reductores manejando una acción. , varios componentes que utilizan el estado de varios reductores, etc. Esa es una de las preguntas n. ° 1 que respondo en el trabajo y en otros lugares, y es muy útil. Así que la herramienta para ayudar en esa área no debería perder esto (además, "los interruptores son asquerosos" no es el mejor argumento del mundo).

Entonces, en mi opinión, las llamadas a la acción implicarían vincular buenos recursos de JavaScript básicos, así como documentar más el "por qué" junto con los conceptos de "inicio", y mantener las cosas simples. Puede crear aplicaciones gigantes en Redux sin tener que aprender muchos conceptos nuevos. Si bien yo mismo soy un tipo observable de redux, he visto cientos de miles de líneas de aplicaciones de código que usan Thunk sin problemas (y he visto pequeñas aplicaciones que hacen un desastre con thunks). Presentar muy pocos conceptos "centrales" y mostrar cómo se pueden aplicar a toneladas de conceptos ayuda mucho.

El "todos los estándares deben reducirse sin importar el costo" es un problema con la comunidad de ingeniería de software en su conjunto en estos días ... eso es más difícil de abordar.

Desde el principio, mi principal preocupación con redux fue que o leía o escribía un código, tenía que saltar entre archivos N, la lógica b / c de la única parte de la interfaz de usuario está dispersa por todo el código base entre acciones, tipos de acción y varios reductores. Realmente me gusta que puedo llegar a cualquier parte del árbol de estado desde cualquier lugar en la interfaz de usuario y puedo cambiar las diferentes partes del estado en respuesta a una sola acción (razones principales por las que uso redux), pero las más partes de el estado que cambio en respuesta a una sola acción, más borrosa se vuelve mi lógica. No puedo simplemente leer o escribir lo que sucedió cuando el usuario hizo esto o aquello. Pero lo que quiero es que se pueda describir así:

// meta code
dispatch(ACTION);

onAction = {
  ACTION: [
    // handler 1: hide spinner here,
    // handler 2: change status there,
    // handler 3: update entity
  ],
};

Al final se me ocurrió redux-interactions + redux-tree y estoy bastante feliz con eso hasta ahora.

Enfoque en nuestro proyecto actual:

tenga en cuenta, sería muy diferente según los requisitos de la aplicación :) una vez que agreguemos actualizaciones de objetos en tiempo real, tal vez las sagas u observables proporcionen un beneficio sobre el procesador / promesa

  • redux-thunk
  • promesa de middleware
  • nuestro "api wrapper", que es un envoltorio alrededor de la aplicación de plumas del cliente, service(name, method, ...opts) que es un creador de acciones con una carga útil que es una promesa para llamar a nuestra API (es decir, el middleware de promesa lo recoge y envía x_FULFILLED , x_PENDING y x_REJECTED ). también podría sobrescribir el nombre de la acción para esto.

Primero usamos componentDidMount() para llamar a nuestra API, almacenar datos en el estado del componente. Sin embargo, usamos nuestro contenedor de API para esto, lo que significa que una acción aún se envía (y se registra mediante el middleware del registrador, incluido el meta, que es la información de solicitud), y si así lo deseamos, refactorizar para usar la tienda para ese componente, todo lo que necesitamos. es agregar un reductor que escucha la acción. Comenzamos usando solo el estado local, y refactorizamos en redux cuando el estado de ese componente necesita ser accedido / modificado desde otro componente. Dicho esto, veo el atractivo de usar redux en todas partes, ya que proporciona un rastro de papel para todo. Dado nuestro equipo actual y el cronograma de aplicaciones, simplemente no es beneficioso para nosotros.

He jugado un poco con redux-saga, pero dado que nuestro flujo asincrónico más complicado es el inicio / cierre de sesión, que funciona (y el código no es terriblemente complicado), no es una gran razón para cambiar (pero podría valer la pena para probar razones: iterable + mocks es una buena forma de probar). redux-observable No veo el beneficio inmediato a menos que los observables proporcionen un beneficio, por ejemplo, si desea hacer doble clic en los eventos de manera agradable.

Nos hemos alejado un poco del estándar al tener nuestras propias funciones de fábrica para devolver reductores y tener nuestros propios reductores de orden superior además de la funcionalidad personalizada (por ejemplo, un reductor en la parte superior del "paginador" para que el contenido esté paginado pero pueda tener acciones para modificar un elemento).

Lo que creo que se debe hacer es un tutorial gigante que trabaja desde una aplicación de reacción básica, demostrar problemas que surgen con la comunicación entre componentes, luego introducir redux, luego seguir adelante, demostrar problemas que ocurren en situaciones específicas y cómo pueden ser ayudado con redux-x . Es decir, una guía sobre cuándo y qué usar. Definitivamente hay algunas publicaciones de blog que existen con discusiones en esta dirección.

Lo que también es relevante es mi resumen que se me ocurrió para los patrones utilizados en gothinkster / react-redux-realworld-example-app

La mayoría de las personas que conozco que usan redux en gran medida, terminan alejándose de redux-thunk ya que encuentran que no escala muy bien

Entiendo lo que está diciendo, pero aquí está mi otra preocupación: estamos viendo cada vez más evidencia anecdótica de que un gran grupo de desarrolladores de JS ni siquiera está usando _funciones de flecha_ y otras características de línea de base de ES (6 | 2015) todavía , debido a la falta de comprensión, intimidación, etc. Esperando que las personas que quieran comenzar con Redux, y que puedan beneficiarse de aprender los _patrones_ que presenta Redux, primero aprendan observables o generadores, ¿creo que es probable que pregunten demasiado?

Redux-thunk también es un poco complejo en el sentido de que el middleware redux en general dobla tu cerebro, pero al menos son solo funciones / devoluciones de llamada, que son fáciles de captar si estás escribiendo JS. Realmente me gusta la idea de tener un paquete completo de herramientas relacionadas para comenzar, disponible a través de una sola descarga, incluso si se presenta como "learn-redux" en lugar de "best-practice-always-redux". De manera similar a cómo la aplicación create-react-app necesita ajustes a medida que aprende todas las cosas que configuró para usted, esto podría alentar su propio ajuste, tal vez mostrar cómo convertir una configuración simple de redux-thunk para usar sagas, etc. como su propia forma de "expulsar" ...

Solo algunos pensamientos.

Entiendo lo que está diciendo, pero aquí está mi otra preocupación: estamos viendo cada vez más evidencia anecdótica de que un gran grupo de desarrolladores de JS ni siquiera están usando funciones de flecha y otras características básicas de ES (6 | 2015) todavía. , debido a la falta de comprensión, intimidación, etc. Esperando que las personas que quieran empezar con Redux, y que puedan beneficiarse de aprender los patrones que introduce Redux, aprendan primero los observables o generadores, ¿creo que es probable que estén pidiendo demasiado?

¡Bingo! Estamos en un entorno en el que MUCHAS personas son nuevas en JS (o "conocen" JS, pero no es su especialidad y comienzan desde lo más profundo). Especialmente si esas personas son ingenieros de software con experiencia de otro ecosistema (java, rieles, etc.), intentarán aplicar rápidamente los conceptos que conocen antes de aprender los que no, y no funcionará del todo y se atascarán. Sin embargo, no sé cuál es la mejor manera de convencer a la gente de que comprenda en profundidad JS antes de saltar a un patrón de diseño funcional de UX.

Tenga en cuenta que los documentos de Redux tienen una sección sobre Reducción de código repetitivo para aquellos de ustedes que leen que están buscando algo ahora y no quieren adoptar una biblioteca completa sobre Redux.

Deberíamos tener un poco de cuidado con esta discusión y darnos cuenta de que probablemente ya se haya eliminado mucho. El equipo de Redux ha escuchado, considerado y rechazado muchas cosas que probablemente se propondrán aquí. Es muy posible que no salga nada de esta discusión si solo peleamos por cosas que ya se han discutido.

Dicho esto, creo que es una gran idea hablar sobre formas de hacer que el marco sea más accesible para todos (nuevos y experimentados).

Todo lo que proponga para reducir el texto estándar debe ser tal que sea posible volver a lo que se encuentra debajo de la abstracción cuando sea necesario. No es divertido adoptar una abstracción solo para dejarla caer más tarde y volver a las cosas de nivel inferior porque necesitabas una cosa adicional en la que los autores de la abstracción no pensaron.

La curva de aprendizaje de Redux puede ser empinada, pero una vez que comprende los conceptos, la necesidad de
las capas de abstracción a menudo desaparecen

Me pregunto, si este es el caso, ¿qué partes de Redux estamos sugiriendo mejorar? ¿Qué partes eliminarías o abstraerías que no necesitarías volver a agregar de inmediato?

Este es un diagrama de todo el ciclo de vida de react / redux que hice para una charla en el trabajo hace un año:
React Redux Lifecycle

Hay bastantes partes de esto, pero no puedo imaginar que Redux funcione tan bien sin ninguna de ellas. Los contenedores son un poco molestos a veces, pero si los elimina, acopla profundamente su lógica de vista con su diseño de datos. Si elimina las acciones, básicamente es MVC nuevamente, lo que no tiene el objetivo de usar Redux en primer lugar. La "vista" en ese diagrama apenas existe porque se puede modelar como una función que se suscribe a la tienda y representa los componentes de reacción.

No creo que haya mucho texto estándar para eliminar en el marco general en sí. Tal vez se esté refiriendo al texto estándar en las partes individuales del marco, como en creadores de acción, reductores o contenedores. En ese caso, los consejos de la página Reducing Boilerplate mencionada anteriormente abordan la mayoría de esas cosas. No necesitamos nada más para hacerlo "mejor". (Nota: no es que no esté dispuesto a agregar algo para mejorar las cosas, simplemente no lo veo todavía).

Tal vez esto no sea tanto un problema de reducción de repetición, sino un problema de mejora de la educación de Redux. Si el marco es difícil de asimilar para los principiantes, es posible que debamos mejorar los documentos de Redux y hacerlo más accesible. Quizás algunos de los consejos de reducción estándar deban anunciarse de manera más agresiva en los documentos.

Reducir la cantidad de pasos necesarios (repetitivo) no siempre resuelve el problema. Para enfatizar mi punto desde el principio de mi publicación, no querrás escribir una abstracción que se deseche porque no pensaste en todas las formas en que la gente necesitaría usarla.

Una buena discusión hasta ahora. Permítanme arrojar algunos ejemplos rápidos de quejas comunes relacionadas con el "estándar" que veo:

  • "¿Por qué tengo que escribir funciones de 'creador de acciones' solo para devolver un objeto inmediatamente?"
  • "¡Tengo que tocar MUCHOS archivos para agregar una nueva característica simple! Además, sigo repitiendo los mismos nombres una y otra vez para constantes y nombres de funciones y ..."
  • "¿Por qué necesito estas cosas de 'middleware' solo para hacer una llamada AJAX?"
  • "¿Por qué tengo que usar declaraciones de cambio para todo?"
  • "¿Por qué necesito esta cosa dispatch ? ¿Por qué tengo que resumir todas estas funciones para que funcionen?"

Y algunos ejemplos concretos de este tipo de comentarios:

Y para descartar inmediatamente algunas respuestas a esas preocupaciones "repetitivas": de las cinco categorías enumeradas, sólo se _requiere_ el "uso de dispatch ". Para el resto:

  • No tienes que usar creadores de acciones, pero es una buena práctica para mantener la coherencia (según mi publicación Idiomatic Redux: ¿Por qué usar creadores de acciones? )
  • No es necesario _ tener_ archivos completamente separados para los creadores de acciones, las constantes de acción y los reductores. El patrón de "patos" es un método popular para juntarlos todos en un archivo. Eso tiene la desventaja de "ocultar" la capacidad de que varios reductores escuchen una acción. En última instancia, a Redux no le importa cuál es la estructura de su archivo.
  • _Puedes_ hacer trabajo asincrónico fuera de Redux por completo, como en un componente. Pero, según la descripción de Dan en ¿Por qué necesitamos middleware para el flujo asíncrono en Redux? , normalmente es bueno extraer esa lógica fuera de los componentes, y el middleware proporciona una "escapatoria" para realizar un trabajo asíncrono mientras se tiene acceso a la tienda Redux.
  • Definitivamente _no_ tiene que usar declaraciones de cambio en reductores, son simplemente la forma más "obvia" de manejar múltiples valores para una variable dada. Las tablas de búsqueda, las declaraciones if / else y cualquier otra cosa que desee están bien (según las preguntas frecuentes: ¿Tengo que usar declaraciones de cambio? )
  • Usted _de_ necesita llamar a store.dispatch() para que suceda algo útil; esa es una decisión de diseño básica de Redux. La vinculación de creadores de acciones hace posible pasarlos a componentes secundarios desconectados y aún así enviarlos cada vez que se llama a la función.

Entonces, en general, no hay casi nada fuera de estas preocupaciones "estándar" que sea _requerido_. Es una combinación de ejemplos de los documentos y "buenas prácticas de programación", como la eliminación de duplicados de código y la separación de preocupaciones.

Creo que las preguntas planteadas por @markerikson son realmente justas y también las he hecho yo mismo en algún momento en el pasado.

Redux es, en cierto sentido, una biblioteca de "bajo nivel" para el modelado de datos. Como cualquier biblioteca de bajo nivel, expone muchas cosas que podría abstraer fácilmente para dar cuenta de la mayoría de los casos. Creo que la razón por la que @gaearon no lo hizo originalmente es porque quería mantener la biblioteca lo más pequeña y flexible posible. Gracias a esa decisión, podemos construir muchas cosas diferentes sobre Redux sin necesidad de tener todo en el núcleo de Redux.

Tal vez deberíamos considerar que el camino correcto podría ser desarrollar y estabilizar una buena biblioteca sobre Redux (¿como Jumpstate?). Comenzamos por enseñarle a la gente eso, y luego les damos un camino fácil para usar Redux directamente cuando lo necesiten.

No creo que Redux necesite mucho más en su base de código central y no veo ninguna parte de ella que deba abstraerse permanentemente. (Si lo hace, avíseme: sonríe :) En mi opinión, no hay mucho que ganar agregando o quitando cosas del núcleo de Redux.

Mejorar una biblioteca hasta el punto en que sea lo suficientemente estable y flexible para que todos la usen es probablemente una mejor opción. Como dijiste, no se requiere mucho del "texto estándar", así que eliminémoslo en una biblioteca en la parte superior de Redux en lugar de modificar el propio Redux.

Un ejemplo de que esto sucede en otra comunidad es el lenguaje de programación Rust. Existe una biblioteca de E / S sin bloqueo para el lenguaje de programación Rust llamada "mio" . Se enfoca en ser pequeño y de bajo nivel como lo hace Redux. La cuestión es que prácticamente nadie lo usa directamente porque sería muy difícil y lleno de repetición. Casi todo el mundo usa otra biblioteca llamada tokio que se basa en mio y la hace extremadamente útil y ergonómica. De esta manera, cualquier persona que necesite la plomería de mio puede usarla directamente, pero cualquiera que solo quiera hacer algo rápidamente puede usar tokio.

Deberíamos adoptar un modelo similar.

Para ampliar un par de comentarios de

Hubo un comentario reciente en el n. ° 775 que creo que captura bien las cosas:

Redux es un marco genérico que proporciona un equilibrio entre la estructura suficiente y la flexibilidad suficiente. Como tal, proporciona una plataforma para que los desarrolladores creen una administración de estado personalizada para sus casos de uso, al tiempo que pueden reutilizar cosas como el depurador gráfico o el middleware.

Así que sí, Redux es "solo un patrón" en muchos sentidos. La biblioteca central realmente tiene características completas: los únicos cambios semiplanificados reales son cosas como la reestructuración propuesta del potenciador (# 1702, # 2214), y posiblemente hacer que combineReducers más flexible (# 1768, # 1792, etc. ).

Han pasado casi dos años desde que se creó Redux, y ahora tenemos una idea bastante clara de cómo la gente lo está usando. Como ejemplo, @jimbolla recopiló una lista de todos los mejoradores de tiendas conocidos en el n. ° 2214 y clasificó cómo funcionan y para qué se utilizan. Todavía soy un gran admirador de la simplicidad y flexibilidad de Redux, pero me encantaría ver algunas abstracciones aún idiomáticas además de Redux que simplificarían el uso general y resolverían problemas para las personas.

Otro conjunto de temas relacionados con la semi-y algo que tengo un interés personal en distintos, son las ideas de la "lógica encapsulada / componentes" (por @slorber 's 'frontend escalable con Elm / Redux' parque infantil ), y "plug -y-play configuración de Redux "(como se ve en experimentos como https://github.com/brianneisler/duxtape/issues/1, https://github.com/jcoreio/redux-features/issues/7, etc.). La configuración de la aplicación y el estado global es excelente para algunos casos de uso, pero no tanto para otros.

Como punto relacionado interesante, @toranb ha hecho un gran trabajo creando un contenedor Ember para Redux en https://github.com/ember-redux/ember-redux . El mundo Ember está _realmente_ en la "convención sobre la configuración", por lo que ember-redux establece una configuración de tienda predeterminada razonable, que incluye redux-thunk y demás. Algún tipo de enfoque como ese podría ser útil.

Entonces sí, estoy lanzando un montón de pensamientos diferentes aquí, pero están relacionados de varias maneras. En general, quiero reducir las barreras para aprender y usar Redux, y permitir casos de uso más avanzados en todos los ámbitos.

Redux es una API general, no especializada. Esto lo hace más detallado, al mismo tiempo que cubre más casos. Su poder está en un software complejo, mientras que cualquier proyecto nuevo o simple está más allá del alcance de la necesidad.

Sin embargo, puede crear especializaciones además de las API generales. Por ejemplo, uso https://github.com/acdlite/redux-actions que reduce el texto estándar para casos comunes. Todavía uso todo el poder de redux y simplemente tener esa interfaz no sería suficiente para mis necesidades.

El otro problema es que las personas nuevas que no han experimentado el dolor de las aplicaciones increíblemente complicadas se preguntan cuál es el punto. Bueno, para ellos probablemente ni siquiera deberían usar redux hasta que hayan experimentado ese dolor, pero la serie de cabeza de huevo de Dan puede patearlos más allá de este punto con bastante facilidad.

https://egghead.io/courses/getting-started-with-redux
https://egghead.io/series/building-react-applications-with-idiomatic-redux

Referencia: El espectro de la abstracción: https://www.youtube.com/watch?v=mVVNJKv9esE

Como se mencionó, redux-actions es bastante bueno para eliminar algunos repetidos, eliminar constantes de la ecuación adjuntando .toString es una idea realmente genial que me gusta, sin embargo, prefiero escribir esta lógica yo mismo que usar redux-actions yo mismo, pero esa es una elección personal para mantener mi código más pequeño.

En mi humilde opinión, debería haber un mecanismo incorporado (¿argumento de devolución de llamada de subscribe ?) Para observar el flujo de acciones enviadas (sé que se puede hacer en un middleware, pero ese es un caso de uso bastante restrictivo, ya que no se puede usar afuera, es decir, por componentes o connect )

A menudo enseño redux a otras personas y puede ser bastante abrumador por las siguientes razones

  • Muchas partes móviles: tienda, estado, reductores, creadores de acciones, acciones, acciones asíncronas, middleware, componentes conectados
  • Bibliotecas. Para una aplicación simple que se comunica con una API REST, necesita: redux, react-redux, redux-thunk (u otros) + bibliotecas adicionales si desea probar cosas
  • Cantidad de lugares en los que debe colocar el código (consulte _partes móviles_)

Creo que redux es una gran biblioteca que tiene mucho sentido en sí misma y creo que tiene grandes abstracciones y es súper escalable cuando se usa correctamente. También aprecio que redux se pueda usar con cualquier biblioteca de interfaz de usuario, pero creo que en la mayoría de los casos se usará con react.

En general, creo que mucha frustración proviene de las muchas partes móviles.

Aquí hay algunos pensamientos que tuve. Todo lo cual se puede construir sobre redux para que pueda permanecer como está.

  • Proporcione una biblioteca como react redux que, además, viene con soporte para acciones asíncronas integradas.
  • Muchas acciones asíncronas están hablando con una API REST, así que proporcione un middleware idiomático para eso
  • Escriba componentes inteligentes como componentes reales en lugar de usar connect. Luego pueden renderizar componentes tontos en su método render
  • Prescriba un diseño de archivo escalable para _componentes de contenedor_, _componentes inteligentes_, _componentes de volcado_, _ creadores de acciones_ y _reductores_.
  • Proporcione un _redux-cli_ para generar código, por ejemplo, redux action loadUsers
  • Estandarice en una capa asíncrona como redux-saga o redux-observable e inclúyalo en los documentos (sería bueno tener _un_ lugar para consultar para la mayoría de los asuntos de redux)
  • predeterminado a las funciones de lenguaje extendidas (por ejemplo, decoradores (@connect)) o TypeScript para hacer las cosas menos detalladas en particular mapStateToProps y mapDispatchToProps (mobx requiere decoradores y la sintaxis es sencilla)

T

De acuerdo, redux-actions es un buen ejemplo de algunas abstracciones simples que eliminan el texto estándar.

Déjame preguntarte esto: Create-React-App tiene el paquete react-scripts , que tiene configuraciones de Babel y Webpack precompiladas, y viene con un montón de valores predeterminados sensibles incorporados. ¿Cómo se vería un paquete redux-scripts ?

Estoy de acuerdo con algunos de los otros comentarios (negativos) sobre redux-thunk . No se lo recomendaría a principiantes (probablemente ya no lo recomendaría):

  1. Parece mágico empezar.
  2. Realmente no quita tanta placa de caldera. Dado un proceso asincrónico más complejo, tener que obtener dispatch de los accesorios y pasarlo resulta ser solo una pequeña parte del código.
  3. Da como resultado creadores de acciones que no puede componer juntos en flujos de trabajo más grandes.
  4. Un último punto que no puedo articular muy bien acerca de convertir el estilo redux en más un marco que una biblioteca: confías en el marco para llamar a tu código, en lugar de llamar a la biblioteca.

Lo usamos bastante en una aplicación React-Native, y fue principalmente útil, pero tuvimos problemas para componer acciones juntas (piense en "cargar perfil después de iniciar sesión correctamente"), debido a que los creadores de acciones redux-thunk devuelven efectivamente void (es decir, no tener nada como una promesa de usar para secuenciar la siguiente acción).

Tiende a animar a la gente a pensar que "la única forma de hacer algo es dispatch inmediatamente desde el controlador de eventos / devolución de llamada de React". Y como estábamos usando connect de react-redux y nos apoyábamos mucho en mapDispatchToProps , tendíamos a olvidar que nuestros controladores de eventos podían ser funciones simples.

(tenga en cuenta que la aplicación anterior se escribió principalmente a principios del año pasado, y realmente no nos mantuvimos al día con lo que estaba sucediendo en el ecosistema Redux, por lo que puede estar desactualizado).

@bodhi : sin desviarme demasiado de la tangente, no estaría de acuerdo con algunas de esas conclusiones. redux-thunk tiene 11 líneas de largo, y hay algunas explicaciones agradables como "¿Qué es un Thunk?" . Thunks _son_ componibles en _alguna_ extensión, y creo que generalmente es más fácil decirle a alguien "escriba estas dos líneas de declaraciones de función, luego haga sus llamadas AJAX y demás aquí". Tengo una publicación que analiza algunas de las diversas compensaciones de los thunks (y hasta cierto punto las sagas) en Idiomatic Redux: Thoughts on Thunks, Sagas, Abstraction, and Reusability .

Estoy de acuerdo en que debería haber una forma _alguna_ "bendecida" o "incorporada" de manejar los efectos secundarios en alguna capa de abstracción hipotética. Las sagas y los observables son geniales, si entiendes cómo usarlos. Simplemente no sé si serían apropiados, dado que un objetivo potencial aquí es proporcionar un camino fácil para aprender y usar Redux.

Encuentro que usar redux-thunk no se trata solo de hacer algo de forma asincrónica, sino también de hacer algo que depende del estado actual. Interfaz muy limpia y sencilla, y fomenta el uso de creadores de acciones.

Bodhi: Quizás un poco fuera de tema, pero pensé que quizás vale la pena mencionar que el envío no devuelve vacío, devuelve el resultado de su función interna. Entonces, si, por ejemplo, devuelve una promesa, puede encadenar acciones fácilmente. Consulte la sección sobre composición en el archivo Léame:
https://github.com/gaearon/redux-thunk/blob/master/README.md

Aparte de eso, me gustaría agradecer a la comunidad por tener esta discusión abierta, muy interesante para escuchar los pensamientos e ideas de todos.
Personalmente me apego a los thunks hasta ahora, pero tratando de separar claramente "lo que sucedió" de "cómo debería cambiar el estado". Veo bastantes instancias en nuestro código donde cometemos ese error (usando acciones para decirle a los reductores qué hacer, en lugar de que los reductores simplemente reaccionen a lo que sucedió), por lo que sería bueno ver alguna biblioteca que de alguna manera lo hiciera más difícil de hacer (aún no vendido en sagas).

El 19 de marzo de 2017, a las 23:48, Bodhi [email protected] escribió:

Estoy de acuerdo con algunos de los otros comentarios (negativos) sobre redux-thunk. No se lo recomendaría a principiantes (probablemente ya no lo recomendaría):

Parece mágico empezar.
Realmente no quita tanta placa de caldera. Dado un proceso asincrónico más complejo, tener que obtener el envío de los accesorios y pasarlo resulta ser solo una pequeña parte del código.
Da como resultado creadores de acciones que no puede componer juntos en flujos de trabajo más grandes.
Un último punto que no puedo articular muy bien acerca de convertir el estilo redux en más un marco que una biblioteca: confías en el marco para llamar a tu código, en lugar de llamar a la biblioteca.
Lo usamos bastante en una aplicación React-Native, y fue principalmente útil, pero tuvimos problemas para componer acciones juntas (piense en "cargar perfil después de iniciar sesión correctamente"), debido a que los creadores de acciones redux-thunk devuelven efectivamente vacío (es decir, tener nada como una promesa de usar para secuenciar la siguiente acción).

Tiende a animar a la gente a pensar que "la única forma de hacer algo es enviar inmediatamente desde el controlador de eventos / devolución de llamada de React". Y como estábamos usando connect de react-redux y apoyándonos mucho en mapDispatchToProps, tendíamos a olvidar que nuestros controladores de eventos podían ser funciones simples.

(tenga en cuenta que la aplicación anterior se escribió principalmente a principios del año pasado, y realmente no nos mantuvimos al día con lo que estaba sucediendo en el ecosistema Redux, por lo que puede estar desactualizado).

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub o silencia el hilo.

(perdón por continuar la tangente, pero ...)

Vale la pena mencionar que el envío no devuelve vacío, devuelve el resultado de su función interna.

¡Eh, genial! Supongo que nunca miré demasiado de cerca la documentación antes de intentar encontrar otra forma de resolver nuestros problemas.

Lo más valioso que hizo que Redux fuera mucho más fácil para mí es tratar las acciones como eventos y no como comandos . Esto elimina por completo la lucha para decidir cómo diseñar acciones y qué poner en ellas.

Los componentes no tienen que saber cómo la interacción del usuario debería afectar el estado, solo le dicen al mundo exterior lo que sucedió dentro de ellos, por ejemplo, "botón X pulsado" . Cuando usa acciones como comandos, introduce efectivamente un enlace bidireccional entre el componente y el estado.

Los reductores no están vinculados a los componentes, representan el estado de la aplicación y no el estado del componente , y son la única parte que realmente sabe cómo cambia el estado. No existe una barrera cognitiva en el manejo de una sola acción en múltiples reductores porque una acción no es una declaración "qué hacer con el estado" .

Esto también elimina cualquier caso para enviar múltiples acciones de forma sincrónica.

Cualquier caso para enviar una sola acción desde varios lugares también desaparece. Puede mantener a los creadores de acciones cerca del componente, lo que facilita el seguimiento del componente que envió la acción.

Al mirar el registro de acciones en DevTools, puede ver un historial completo de lo que sucedió dentro de su aplicación y es fácil ver el segmento de estado concreto afectado por la acción. La historia sigue siendo la más corta posible.

Este enfoque basado en extracción hace que el flujo de datos sea verdaderamente unidireccional y se apila naturalmente con bibliotecas de administración de efectos secundarios como redux-saga o redux-observable .

@aikoven, aunque estoy totalmente de acuerdo con esto (definitivamente hubo mucha discusión en el pasado comparando redux con el abastecimiento de eventos), ¿qué haces con cosas como FETCH_USER , que es muy común de ver (y algo que necesita ser hecho). Eso parece más "similar a un comando" que "similar a un evento".

@blocka Siempre hay algún evento que resulta en una solicitud de red. La solicitud en sí puede estar envuelta en acciones FETCH_USER_STARTED y FETCH_USER_DONE / FETCH_USER_FAILED , que es la forma en que el resultado de la solicitud termina en el estado.

👍 por redux-actions

Lo que también me gusta de él, aparte de simplemente reducir el texto estándar, es que se siente como una extensión muy natural de redux. Para algo como jumpstate , siento que la implementación se está alejando un poco más, y ahora tendré que aprender dos cosas en lugar de una.

Entonces, mi punto es que cualquier complemento que agreguemos para reducir la placa de la caldera debería parecerse mucho a trabajar con redux, aunque con una API menos detallada.

Gran parte del texto estándar es el mismo texto estándar que tiene en cualquier entorno. Cuando te encuentras con una duplicación, generalmente la resolvemos con una abstracción personalizada. Estas abstracciones, muy a menudo, no son útiles fuera de su proyecto actual, y una "bala de plata" simplemente no puede existir. Los requisitos de cada proyecto son diferentes.

Lo mismo con redux. Si está de acuerdo con que necesita una acción FETCH_X_STARTED , y un creador de acciones fetchX() y un reductor para manejar eso, etc., ¡no dude en hacer su propia abstracción!

Culpar a redux por repetición es como copiar y pegar todo su código, y luego culpar a javascript por tener demasiada repetición.

Encuentro que usar redux-thunk no se trata solo de hacer algo de forma asincrónica, sino también de hacer algo que depende del estado actual. Interfaz muy limpia y sencilla, y fomenta el uso de creadores de acciones.

Usar redux-thunk para código síncrono no es una gran idea y debería mencionarse en los documentos.
Si componen muchas funciones juntas, no está seguro de que el flujo de despacho no dependa del orden, por lo que es más difícil razonar y probar.

Me parece mejor tener creadores de acciones puras y simplemente usar acciones por lotes para modificaciones de estado más complejas. De esta manera, solo tiene funciones puras para probar.

Recomiendo esta publicación de blog para comprender mejor: http://blog.isquaredsoftware.com/2017/01/idiomatic-redux- Thoughts - thunks - abstraction - reusability/

@Machiaweliczny gracias por el artículo. Supongo que la pregunta para mí es más sobre dónde terminas poniendo tu lógica de negocios (como se explica en https://medium.com/@jeffbski/where -do-i-put-my-business-logic-in-a- react-redux-application-9253ef91ce1 # .3ce3hk7y0). No estás diciendo que tu flujo de despacho (thunk, épico, saga, lo que sea) nunca debería tener acceso al estado actual de la aplicación, ¿verdad?

@dfbaskin

Tenga en cuenta que Redux no es un desarrollo impulsado por dominios. La "lógica empresarial" es una preocupación mucho más confusa aquí, y es más "qué firma de función del concepto se ajusta mejor a la lógica que estoy tratando de implementar". Su "lógica empresarial" se extiende a través de selectores, reductores, creadores de acciones y "orquestadores" (¿tenemos una palabra mejor para esto todavía?) Dependiendo de lo que necesite.

El reductor, que es (state, action) => state es donde generalmente debería estar la "lógica que depende del estado". Y efectivamente, en cosas como la Arquitectura Elm, toda esa lógica está en la función "actualizar" (el equivalente a nuestro reductor).

Desafortunadamente en Redux, el reductor solo puede manejar lógica síncrona. Entonces, la "lógica de negocios" asincrónica que depende del estado debe obtenerla del componente a través del envío (si el componente tiene esa información, que no siempre es así), o mediante el concepto de orquestador que elija (thunk, sagas, epic), que tienen acceso al estado para eso.

Si no fuera por la limitación del reductor, no sería necesario. De hecho, lo ves cuando las personas usan redux-saga o redux-observable: sus acciones / creadores de acciones generalmente se vuelven casi triviales (en la mayoría de los casos, más o menos algo de normalización o formato), y la saga / épica son casi "reductores alternativos". , en eso ahora tiene otra cosa que tiene acceso a la acción y el estado y devuelve una "cosa", y la complejidad del reductor real se reduce como resultado. Los reductores y los orquestadores están muy relacionados (a veces demasiado, y no es bueno tener 2 construcciones que son intercambiables la mitad del tiempo ... pero es lo que tenemos, también podríamos disfrutarlo)

@Machiaweliczny : como autor de esa publicación de "Pensamientos sobre Thunks", puedo asegurarles que "evitar usar thunks para el trabajo sincrónico" es lo opuesto a lo que estaba tratando de decir :)

Más buena discusión, pero estamos empezando a desviarnos un poco del tema. (¿Es un cobertizo para bicicletas lo que veo allí? :))

Permítanme señalar las preguntas originales:

  • ¿Cómo sería el uso idiomático de Redux con "menos repetitivo"? ¿Cómo podemos brindar soluciones a esas quejas?
  • ¿Qué posibles abstracciones podrían crearse que simplifiquen el proceso de aprendizaje y uso, pero sin ocultar realmente Redux (y con suerte proporcionarían una ruta de migración / aprendizaje a Redux "base")?
  • ¿Cuánto de esto podría resolverse con documentos mejorados de alguna manera?

¿Qué pasos concretos podemos implementar para abordarlos?

En el ámbito de los pasos a corto plazo, no controvertidos y procesables, yo diría:

1) Hacer que la tienda sea más fácil de configurar (¿tal vez con una configuración predeterminada? No sé si este sigue siendo el caso, pero Elm solía tener un tipo de "aplicación de inicio" y un tipo de aplicación normal. Se usó la aplicación de inicio para aplicaciones simples y en material de capacitación para cubrir el 90% de los casos en los que la gente recién está aprendiendo. Hasta el día de hoy, admito que no puedo configurar la tienda Redux con middlewares básicos (devtools, thunks) sin buscar las firmas en el documento. No creo que mucha gente diría que los recién llegados necesitan saber cómo configurar los middlewares de una tienda para aprender los conceptos centrales de Redux.

2) Puede que este ya sea el caso, asegúrese de que agregar Redux con la "tienda de inicio" anterior a create-react-app sea lo más fácil posible, para que un recién llegado pueda tener una aplicación Redux en funcionamiento en 2 minutos.

Creo que esto nos llevaría muy, muy lejos.

Editar: por aplicación de inicio, no me refiero a una plantilla de aplicación, sino a un "createStore" que no se puede configurar, pero tiene valores predeterminados razonables que la gente puede importar y terminar con ella. Luego, pueden pasar al createStore "real" cuando lo superen.

Eso suena como un concepto bastante fantástico allí mismo.

El lunes, 20 de marzo de 2017 a las 10:02 a. M. Francois Ward [email protected]
escribió:

En el ámbito de los pasos a corto plazo, no controvertidos y procesables, yo diría:

1.

Hacer que la tienda sea más fácil de configurar (tal vez con un
¿configuración? No sé si sigue siendo así, pero Elm solía tener
un tipo de "aplicación de inicio" y un tipo de aplicación normal. La aplicación de inicio se utilizó para
aplicaciones simples y en material de capacitación para cubrir el 90% de los casos en que las personas
solo aprendiendo. Hasta el día de hoy, admitiré que no puedo configurar la tienda Redux.
con middlewares básicos (devtools, thunks) sin buscar el documento para
las firmas. No creo que mucha gente diría que los recién llegados necesitan
saber cómo configurar los middlewares de una tienda para aprender el núcleo de Redux
conceptos.
2.

Este puede que ya sea el caso, asegúrese de agregar Redux con lo anterior
"tienda de inicio" para create-react-app es lo más fácil posible, por lo que un recién llegado
puede tener una aplicación Redux en funcionamiento en 2 minutos.

Creo que esto nos llevaría muy, muy lejos.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/reactjs/redux/issues/2295#issuecomment-287806663 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AFUmCQYkUwjkCugevDBWC8TOu0HhWJTnks5rnqMWgaJpZM4MhnVF
.

Nuestros módulos hacen uso de combineReducers para que cada segmento de estado en un módulo tenga un reductor dedicado (creo que este enfoque se describe en la sección Reductores de estructuración de los documentos, también conocidos como "reductores de segmento"). Esto hace que sea más fácil razonar porque las declaraciones de cambio son mucho más pequeñas. También permitió que surgieran reductores comunes en nuestra base de código. Los reductores más simples eran idénticos en todos los módulos, excepto por sus tipos de acción, por lo que pudimos reducir el texto estándar al tener funciones auxiliares (¿fábricas de reductores?) Que hacen estos reductores para nosotros por tipo de acción:

const { makeIndicator, makePayloadAssignor } from '../shared/reducers';

const searchModule = combineReducers({
  searching: makeIndicator(c.SEARCH),
  results: makePayloadAssignor(c.SEARCH_RESPONSE, [])
});

Quizás identificar reductores de rebanadas más comunes como este sería una buena manera de aliviar las preocupaciones habituales, donde podrían servir como bloques de construcción primitivos para nuestros reductores.

Esta es la refactorización básica de JavaScript. Como dije antes ... "javascript" tiene un
mucho "repetitivo", hasta que aplique cosas como la abstracción a su código.

Redux es solo javascript. No tiene nada de mágico.

El lunes 20 de marzo de 2017 a las 12:44 p.m., Markus Coetzee [email protected]
escribió:

Nuestros módulos hacen uso de combineReducers para que cada segmento de estado en un
módulo tiene un reductor dedicado para él (creo que este enfoque se describe
en la sección Reductores de estructura de los documentos, también conocidos como "sector
reductores "). Esto hace que sea más fácil razonar porque el cambio
las declaraciones son mucho más pequeñas. También permitió que surgieran reductores comunes
a través de nuestra base de código. Los reductores más simples eran idénticos en todos los módulos.
excepto por sus tipos de acción, por lo que pudimos reducir el texto estándar
tener funciones auxiliares (¿fábricas de reductores?) que hacen que estos reductores para
nosotros por tipo de acción:

const {makeIndicator, makePayloadAssignor} de '../shared/reducers';
const searchModule = combineReducers ({
buscando: makeIndicator (c.SEARCH),
resultados: makePayloadAssignor (c.SEARCH_RESPONSE, [])
});

Quizás identificar reductores de rebanadas más comunes como este sería una buena
manera de aliviar las preocupaciones habituales, donde podrían servir como
bloques de construcción primitivos para nuestros reductores.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/reactjs/redux/issues/2295#issuecomment-287820595 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AACourLpL5--NJiRzrWmKFJ31cl5DXJrks5rnqzxgaJpZM4MhnVF
.

Estoy de acuerdo con la mayoría de los comentaristas que dijeron que es mejor explicar los patrones comunes de reducción que desarrollar un reductor estándar. Mis compañeros de equipo y yo comenzamos a trabajar con redux hace 1,5 años y estábamos confundidos sobre las cosas más simples: que redux es principalmente un abastecimiento de eventos, que la misma acción puede ser manejada por varios reductores, esa acción puede contener toda la enidad del negocio, no solo su identificación. , que los reductores son solo funciones y usted es libre de hacer lo que quiera con ellos - componer, generar, dividir, etc. Cometimos errores comunes - usamos acciones como comandos remotos y nos preguntamos por qué no usar las llamadas a métodos clásicos; creó enormes middlewares y evitó redux-saga porque "los generadores son demasiado complicados" (¡aunque redux-saga es excelente!), creó archivos largos con enormes interruptores. Por supuesto, esto se debe a unas habilidades de programación mediocres, pero también a la falta de información estructurada. Hoy en día, la documentación es mucho mejor, ¡muchas gracias a los mantenedores!

Este es un tema muy valioso sobre Redux como biblioteca.

Esta es la refactorización básica de JavaScript. Como dije antes ... "javascript" tiene un
mucho "repetitivo", hasta que aplique cosas como la abstracción a su código.
Redux es solo javascript. No tiene nada de mágico.

Perfecto, @blocka! Creo que este mensaje debe difundirse.

Redux se siente inusual y repetitivo para la gente debido a su enfoque mínimo. Mínimo se siente extraño para un "marco" en general (código mínimo, principios mínimos).

Algunas personas están acostumbradas a escribir código "framework-y" en lugar de escribir JavaScript. Cuando los desarrolladores usan un marco, se espera implícitamente una forma integrada de hacer las cosas. Triste como el infierno pero cierto.

Creo que es más fácil comenzar con Redux que nunca, pero aún debemos dejar en claro que la gente no espera que Redux haga todo. @gaearon dice claramente esto todo el tiempo, pero desafortunadamente la gente está acostumbrada a que los frameworks hagan todo. ¿Por qué deberían motivarse para aprender algo que "no hace mucho"? Angular hace mucho más que Redux. ¿Por qué Redux? La respuesta probablemente sea evidente para todos nosotros en este tema. Pero, ¿está claro para los principiantes?

Ayer escribí un breve artículo al respecto: no culpes a React o Redux . Por supuesto que puedo equivocarme en todo esto.

Existe un precedente de tener capas de abstracción sobre una biblioteca avanzada. Recientemente, Tensorflow incorporó Keras como una abstracción además de la API principal: http://www.fast.ai/2017/01/03/keras/.

Usar TensorFlow me hace sentir que no soy lo suficientemente inteligente como para usar TensorFlow; mientras que el uso de Keras me hace sentir que las redes neuronales son más fáciles de lo que pensaba. Esto se debe a que la API de TensorFlow es detallada y confusa, y a que Keras tiene la API más expresiva y cuidadosamente diseñada que he experimentado. Estaba demasiado avergonzado para criticar públicamente a TensorFlow después de mis primeras interacciones frustrantes con él. Se sentía tan torpe y antinatural, pero seguramente este era mi defecto.

Siento que es una experiencia similar para la mayoría de los principiantes que ingresan a Redux. Reemplace Tensorflow con Redux y Keras con Jumpstate . Redux es muy poderoso, pero la mayoría de los usuarios probablemente no necesiten todo el control disponible. Lo más probable es que vengan de Angular o se les enseñe React + Redux en un bootcamp o al ver varios tutoriales. Si bien Redux no necesita ser simplificado para los nuevos usuarios, tampoco es un anti-patrón para proporcionar una abstracción más fácil que probablemente pueda cubrir el 80% de los casos de uso potenciales.

Todos ustedes, si Redux estuviera bien como está, no estaríamos teniendo esta conversación. Independientemente de si redux es útil o estructuralmente sólido, las personas todavía se sienten "mal" cuando lo aprenden por primera vez. Estos sentimientos son válidos.

Las personas que comentan en este hilo son todas expertas en redux; por supuesto, estamos contentos con redux; hemos interiorizado su filosofía y nos sentimos cómodos haciendo nuestras propias abstracciones para la gestión "repetitiva". No somos la audiencia a la que este hilo intenta servir. Necesitamos sentir cierta

Por ejemplo: aquí hay una queja que escucho con frecuencia sobre redux (que no creo que se haya mencionado en el hilo superior): no es suficiente usar redux, también "necesita" usar react-redux, redux-thunk, redux-actions, etc. .

¿Necesita literalmente usar todos esos otros paquetes para usar redux? No.
¿La mayoría de los usuarios de redux terminarán usando algunos o todos esos paquetes adicionales? Si.

¿Importa la cantidad de paquetes en package.json ? No en realidad no.
¿La cantidad de paquetes en package.json afecta la forma en que se siente la gente? Absolutamente.

Ahora, creo que es justo creer que redux en sí debería permanecer como está, y otro paquete ( create-redux-app o lo que sea) debería encargarse de ensamblarlos. Pero tenemos un problema de complejidad real en nuestras manos y no es suficiente decirle a los usuarios que utilicen RTFM.

Independientemente de si redux es útil o estructuralmente sólido, las personas todavía se sienten "mal" cuando lo aprenden por primera vez. Estos sentimientos son validos

Absolutamente. Pero no todas las personas se sienten así. Algunos lo hacen. Tenga en cuenta que nunca tendrá noticias de personas que no hayan tenido problemas. Solo ves a los que te hacen preguntas o presionan stackoverflow / reactiflux. De los que nunca la necesitan, algunos también necesitan ayuda pero no saben cómo pedirla ... y algunos también lo están haciendo bien, y no querrás empeorar las cosas para ellos ... de lo contrario, lo harán sea ​​el que llegue a los foros en su lugar y será una ganancia neta cero.

Redux no se hizo popular sin ninguna razón. Mucha gente pensó que se sentía muy bien y se lo recomendó a otros :)

Ahora, creo que es justo creer que redux en sí debería permanecer como está, y otro paquete (create-redux-app o lo que sea) debería manejar ensamblarlos juntos.

Me gustó esta idea. Sería posible argumentar que las plantillas existentes ya lo resuelven, pero React también tenía muchas plantillas en el momento en que las personas se quejaban de estar abrumadas con herramientas cuando intentaban ingresar a React. create-react-app fue una gran respuesta a todo esto, porque ya eliminó muchos pasos para que los principiantes ingresen a React _self_.

Pero sigue siendo típico debajo del capó. Por lo tanto,

Sin embargo, no creo que incluir paquetes como redux-thunk en el núcleo de Redux sea el camino a seguir aquí.

Solo para mayor claridad, el tipo de ideas que estoy lanzando no se trata de incluir cosas directamente en el núcleo. Se trata de crear hipotéticamente algún tipo de "configuración prediseñada" o "capa de abstracción fácil de usar" que sería un paquete separado o una herramienta CLI o algo, más en la línea de create-react-app .

Supongo que será mejor que intervenga como autor de Jumpstate / Jumpsuit.

TL; DR:
Redux es difícil de aprender y difícil de configurar / integrar porque es de muy bajo nivel. La comunidad podría beneficiarse de una API redux estandarizada de alto nivel dirigida al caso de uso del 90% para facilitar la curva de aprendizaje e incluso operar como una solución para proyectos más simples. Jumpstate está tratando de resolver esto, pero no es una solución a largo plazo. Necesitamos comenzar a proponer posibles ideas (código real o meta) sobre cómo podría verse esta API.


Redux es muy difícil de aprender desde el principio y, muy a menudo, tan difícil de integrar con nuevos conceptos como lógica asíncrona, efectos secundarios, middleware personalizado, etc. Lo experimenté yo mismo hace poco más de un año cuando era muy nuevo en el ecosistema react.

Solo unos días después de aprender a reaccionar, se me recomendó de inmediato que aprendiera redux. Esta recomendación provino de desarrolladores novatos y con mucha experiencia que habían hecho (o estaban haciendo) lo mismo. Estaba siendo aclamado como la solución de facto para cualquier cosa que se extendiera más allá de setState (aunque mantengamos la puerta de setState fuera de esto 😉). Todo esto por una buena razón, porque redux es increíble.

Inevitablemente llegué a la curva de aprendizaje y, cuando busqué ayuda, me di cuenta de inmediato de que el enfoque de marketing y documentado para redux adoptó un tono de "Redux es difícil, los conceptos son de bajo nivel, la API está bloqueada y solo necesitas pasar eso."

Así que esto es lo que hice junto con todos mis compañeros. Lo hicimos funcionar porque era para lo que fuimos educados. Sin embargo, a lo largo de este viaje, me atreví a crear una capa de abstracción desde el principio que ocultaría de forma temporal y deliberada algunas de las complejidades y características avanzadas que redux tenía para ofrecer.

No necesitaba creadores de acciones personalizadas, no quería preocuparme por mapear acciones y despachadores a componentes y, como muchos otros, opté por un diseño de reductor menos detallado en lugar de una declaración de cambio.

Funcionó fantásticamente. Tan bien, de hecho, que aceleró el proceso de aprendizaje de redux para el resto de mis compañeros y otros desarrolladores que estaban luchando de manera similar con la curva de aprendizaje.

Lo diseñamos de tal manera que el redux avanzado o "idiomático" aún podría usarse cuando lo necesitáramos, pero realmente lo diseñamos para nuestro caso de uso del 90%.

De ninguna manera estoy diciendo que jumpstate cubre todas las bases, de hecho, todavía hay tantas cosas que deben cambiar para que jumpstate se comporte "idiomáticamente" (creadores de acciones personalizables, eliminación de importaciones de acciones globales ... hay muchas) , pero definitivamente ha ayudado a muchas personas a aprender los conceptos básicos y les ha proporcionado un camino para comprender cómo funciona redux en un nivel muy simple. Todo el tiempo recibo un mensaje en la organización slack de Jumpstate que dice que Jumpstate ayudó a alguien a aprender redux.

Si esas personas todavía usan Jumpstate hoy o no, no importa mucho (pero muchas personas todavía lo usan en producción hoy en día). Lo que importa fue la experiencia que tuvieron y la rapidez con la que pudieron volverse productivos en el ecosistema redux.

Algunas ideas más que me vienen a la mente para esta discusión:

  • proponga metaejemplos de cómo se vería un redux simplificado, ¡solo pruébelo!
  • discutir los requisitos y decidir sobre un estándar para las guerras intermedias redux a menudo duplicadas y extremadamente obstinadas. Podríamos comenzar con el manejo asincrónico. Esto podría resolver tanta fragmentación en la comunidad de redux y ayudar a que los esfuerzos de todos hagan una diferencia en la supervivencia a largo plazo y el uso de redux.

¿Cuánto de esto podría resolverse con documentos mejorados de alguna manera?

Mucho. Cuando se trata de la documentación de Redux, creo que en muchos grados es peor que la documentación de AngularJS 1 porque, como la de AngularJS, es innecesariamente detallada, pero a diferencia de la de AngularJS, falla el principio de "mostrar, no decir".

Los documentos de Redux prefieren los fragmentos de código en lugar de la demostración real del código, lo que significa que hay demasiados momentos de "aquí hay un conjunto de código; no le diremos cómo se conecta, pero confíe en nosotros que funciona". La falta de capacidad para ejecutar ejemplos dentro de un navegador significa que el usuario se ve obligado a confiar en sus propios instintos de que lo que están haciendo localmente funciona y si algo no funciona, se quedan solos. Incluso la simple aplicación Todo List creo que no es el mejor ejemplo de "hola mundo" de Redux - podría ser mucho más simple.

Los diagramas ciertamente ayudarían aquí. Por ejemplo, me gusta el de @sunjay ; uno que podría ser incluso mejor es diseñar uno para el ejemplo de la Lista de tareas en sí: cómo se conectan los archivos, etc. desde una vista de alto nivel. Las imágenes casi siempre son mejores para transmitir texto extenso y pueden ayudar a reducir la verbosidad de los documentos. Las imágenes también ayudarían a los principiantes a mantener la concentración y comprender mejor Redux en su conjunto.

Mis dos centavos: por favor, no cambies el núcleo. Su brillantez está en su sencillez. En este punto, agregarle algo probablemente le quitaría el todo.

La facilidad de uso y una mayor abstracción pueden ocurrir en la tierra de los usuarios. Tampoco siento que sea necesario que haya una forma oficial o idiomática de usarlo. Es un contenedor de estado predecible, ¡eso es todo!

Puede sostenerse por sí solo, vamos a ser ❤️

Dicho esto, claro, empaquételo como quiera creando más librerías comentadas encima. Eso es lo que hago yo también, pero no cambiemos el núcleo, por favor.

@HenrikJoreteg , ¡no temas! Estoy casi seguro de que nada de lo que discutamos aquí cambiará el núcleo. El núcleo tiene características completas y se sostiene por sí solo. :)

Mucho. Cuando se trata de la documentación de Redux, creo que en muchos grados es peor que la documentación de AngularJS 1 porque, como la de AngularJS, es innecesariamente detallada, pero a diferencia de la de AngularJS, falla el principio de "mostrar, no decir".

Esto es muy cierto. Una cosa cuando Redux era nuevo es que el documento era escaso, pero lo básico estaba ahí. Mucha gente lo adoptó porque era "muy simple". Pero los recursos en línea ahora intentan mostrar "técnicas del mundo real", que a menudo son simplemente "mi middleware favorito" y "mis herramientas de reducción repetitivas favoritas". La gente se abruma.

Hay algo que decir sobre "menos es más"

@Phoenixmatrix , @Sylphony : entonces, ¿cómo sería una posible renovación de documentos?

Personalmente, para combinarlo con mis sugerencias anteriores de tener una "tienda de inicio", lo dividiría en dos (no 2 sitios / documentos diferentes, sino 2 secciones diferentes).

La "arquitectura Redux", que tendría muchos dibujos sencillos y bonitos, explica acciones y reductores, introduce react-redux y tal vez thunks, utiliza la "tienda de inicio" para limitar cualquier tipo de configuración inicial y muestra lo fácil que puede ser Sería hacer una aplicación simple que haga algunas solicitudes ajax y renderice cosas en la pantalla.

Todo lo demás puede ir en una sección de "exploración" con los conceptos más avanzados. Incluso entonces, probablemente arrancaría muchas cosas. Alguien me señaló hoy que hay una sección sobre tener varias tiendas en una aplicación. Es bueno saberlo, pero sus usos son realmente avanzados. No creo que ningún recién llegado deba tropezar con él sin mirar.

Los mejores documentos siempre son una gran idea, pero no creo que eso resuelva el problema central aquí. Las bibliotecas de abstracción se están escribiendo y adoptando debido a la repetición y la verbosidad de la api de Redux. Esas mismas bibliotecas están fragmentando la comunidad de Redux porque obviamente son necesarias en un nivel u otro. Es frustrante cuando esos mismos autores que están tratando activamente de contribuir al ecosistema son rechazados y descartados públicamente porque "no entienden Redux". Si la comunidad puede, en cambio, crear una abstracción más simple, que no sea parte del núcleo de React, pero "bendecida" hasta cierto punto, entonces todos ganan. Los usuarios incondicionales siguen usando Redux tal como está, otras personas pueden usar una abstracción con una API más fácil / menos detallada.

@derekperkins ¿Cómo llegamos a un consenso sobre una biblioteca "bendecida"? ¿Cómo decidimos qué incluye y quién va a trabajar en él?

Estoy totalmente a favor de algo como esto, pero ¿cómo podemos evitar simplemente crear otra biblioteca que solo algunas personas usan y, por lo tanto, fragmentar aún más el ecosistema?

Xkcd relevante: https://xkcd.com/927/

Sí, el núcleo de redux y el react-redux están lo más cerca posible de un consenso. Incluso redux-thunk y redux-actions están bastante al límite, porque incluso en ese nivel, la mayoría de las personas tienen necesidades diferentes.

Reducir el texto estándar en Redux es una cuestión de "No necesitoasí que lo abstraeré. Pero incluso para los recién llegados, "esa parte" varía drásticamente.

Diablos, tenemos muchas (varias docenas) de aplicaciones redux en funcionamiento y es difícil crear una pila de reducción estándar común porque las diferentes aplicaciones tienen diferentes requisitos. Es fácil cuando tiene una sola aplicación o algunas con los mismos requisitos. Incluso los pequeños difieren bastante.

La idea aquí no es armar un conjunto de herramientas que resuelva todos los problemas para todas las personas. Usando CRA como ejemplo: hay muchas formas de configurar Babel y Webpack y ESLint. Lo que hace CRA es ofrecer una forma única y obstinada de hacer que todos funcionen sin ningún problema por parte del usuario, y selecciona deliberadamente una serie de configuraciones que mejoran las cosas para los estudiantes. Luego permite al usuario tomar el control de la configuración _ si así lo desea_.

Tampoco intenta resolver todos los casos de uso. CRA no intenta abordar la división avanzada de código, múltiples puntos de entrada, SSR o cosas por el estilo. Los documentos de CRA _do_ señalan otras herramientas y opciones que pueden ofrecer más capacidad de configuración y funcionar mejor para ciertos casos de uso.

Esa es una excelente manera de decirlo. Algo para ponerse en marcha rápido que
¿Solo implica instalar redux y esta hipotética capa de configuración? Ese
sería grandioso.

Otra idea que tuve sería una bandera que podría configurar en modo de desarrollo que podría
Esté atento y exponga las oportunidades de aprendizaje incrementales para el usuario. En
de esta manera, la capa de abstracción podría servir como una herramienta didáctica interactiva.
El lunes, 20 de marzo de 2017 a las 4:14 p.m. Mark Erikson [email protected]
escribió:

La idea aquí no es armar un conjunto de herramientas que resuelva todos los problemas
para toda la gente. Usando CRA como ejemplo: hay muchas formas de configurar
Babel y Webpack y ESLint. Lo que hace CRA es ofrecer una única y obstinada
manera de hacer que todos funcionen sin ninguna molestia por parte del usuario, y
elige deliberadamente una serie de configuraciones que mejoran las cosas para
aprendices. Luego permite al usuario tomar el control de la configuración siellos quieren .

Tampoco intenta resolver todos los casos de uso. CRA no intenta
abordar la división avanzada de código, múltiples puntos de entrada, SSR o cosas como
ese. Los documentos CRA hacen punto a otras herramientas y opciones que pueden ofrecer
más configurabilidad y funcionan mejor para ciertos casos de uso.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/reactjs/redux/issues/2295#issuecomment-287914805 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AFUmCactFzsw7etmGGP8MFK6kfNaOzTJks5rnvorgaJpZM4MhnVF
.

@sunjay Sabía qué enlace xkcd era sin siquiera tener que hacer clic. :)

Estoy de acuerdo con @markerikson. Este no es un intento de manejar todos los casos extremos para cada persona. Es una declaración obstinada de los desarrolladores principales de Redux que dice: "Esta es una buena manera de hacer que las cosas funcionen". Hay valores predeterminados cuerdos que se pueden anular si es necesario, pero apuesto a que los valores predeterminados funcionarán para el 80% de los desarrolladores.

Eso puede o no estar escrito en el núcleo de Redux. Sigo pensando que hay un lugar para algo como Jumpstate que hace más que acelerar la curva de aprendizaje.

La curva de aprendizaje de Redux puede ser empinada, pero una vez que comprende los conceptos, la necesidad de capas de abstracción a menudo desaparece.

Creo que eso es cierto hasta cierto punto, pero no significa necesariamente que siempre quieras eliminar la capa de abstracción. Aunque he escrito C en el pasado y entiendo la asignación de memoria, prefiero escribir en Go, donde se maneja la recolección de basura por mí. Según mi ejemplo de Tensorflow anterior, sería más eficaz escribir en las apis de nivel inferior, pero también hay mucho que decir sobre la facilidad de uso de la abstracción de Keras de Python. De manera similar, para Redux vs Jumpstate (o cualquier abstracción que provenga de este problema), no es que el texto estándar no sea necesariamente difícil de escribir, es engorroso para la mayoría de los casos de uso que no necesitan toda la flexibilidad de Redux sin procesar.

Si fuera por mí, me gustaría ver esto:

  • Un subconjunto compatible con Flow / TypeScript que es más fácil de escribir que Vanilla Redux.
  • No enfatizar tanto las constantes (solo haga que el uso de literales de cadena sea más seguro).
  • Manteniendo la independencia de React u otras bibliotecas de vistas, pero facilitando el uso de enlaces existentes (por ejemplo, proporcionando implementaciones mapStateToProps ).
  • Preservar los principios de Redux (acciones serializables, viajes en el tiempo y recarga en caliente deberían funcionar, el registro de acciones debería tener sentido).
  • Admite la división de código de una manera más sencilla desde el primer momento.
  • Fomentar la colocación de reductores con selectores y hacerlos menos incómodos de escribir juntos (piense en paquetes de reductor-selector que son fáciles de escribir y componer).
  • En lugar de colocar a los creadores de acciones con reductores, deshacerse de los creadores de acciones por completo y hacer que el mapeo de muchos a muchos de acciones a reductores sea natural (en lugar de rehuirlo como lo hacen la mayoría de las bibliotecas).
  • Hacer valores predeterminados de rendimiento razonables para que la memorización a través de Reselect "simplemente funcione" para casos de uso comunes sin que los usuarios escriban ese código.
  • Contiene ayudantes integrados para indexación, normalización, recopilaciones y actualizaciones optimistas.
  • Tener soporte de flujo asíncrono comprobable incorporado.

Además del núcleo, por supuesto, aunque está bien marcarlo como algo oficial de Redux.
Además, no escribiré esto. Pero puedes.

Para mí, hace unos meses, cuando aprendí redux , leí el documento pero no lo entendí muy bien, así que dediqué 2 días a leer el código src , luego cada descripción sobre api de el doc se aclara .

Y luego, el pensamiento sobre los capítulos de "diseño de estado", "división de reductores", "diseño de middleware", "solución asíncrona" ...... también se aclara con el desarrollo del proyecto los próximos meses.

Entonces, creo que leer el código src es el paso más apropiado para aprender redux , y solo después de eso, puede comprender y explorar el entorno de redux más fluida.

soporte asincrónico por defecto.

Me refiero a que no es necesario utilizar otro complemento como redux-thunk, redux-saga .

soporte asincrónico por defecto

Lo hace, es solo que la gente lo mira durante 0,5 segundos antes de buscar algo mejor. Nada le impide llamar a las API dentro de sus componentes y luego llamar al despacho en las resoluciones de devolución de llamada / promesa. Es solo que la gente quiere exteriorizarlo de inmediato (incluido yo). Pero puedes hacer async sin problemas sin ningún middleware.

El comentario de @gaearon es perfecto, ya que resalta cuán amplio es el alcance. Amo y aprecio totalmente la precisión, la elegancia y el poder del Redux 2.0 que él propone, ¡y sin embargo, casi ninguna de esas mejoras es relevante para mí!

De hecho, lo encuentro fascinante.

Mi propia biblioteca de abstracción de Redux hace casi todo lo contrario. Encuentro un valor inmenso en las acciones de un solo reductor, en agrupar funciones de reductor atómico con sus códigos de acción y selectores, en eliminar cadenas por completo a favor de claves de objeto. Es mi propia solución al 90%, más similar a la CRA en actitud que a cualquier otra cosa.

El punto interesante tiene mucho que ver con: ¿qué problemas estamos tratando de resolver? Hay muchos problemas, con varios espacios de solución diferentes disponibles. Si Dan construye Redux 2.0 de la forma en que lo describió, ¡yo también reconstruiría mi propia biblioteca de abstracción!

@jbellsey Redux es nivel mundial , pero en un alcance definido, puede tener instancias infinitas de tienda redux pero puede combinarlas. Básicamente, esto es útil para bibliotecas. Si ve una biblioteca que habla de redux en el interior, puede beneficiarse de ...

¿Qué problemas estamos tratando de resolver?

Estado global de la aplicación. R eliable un E sthetics D elivered T nified e X tensible: heart:

Nadie quiere globales. Pero todo el mundo necesita uno: tm:

Por favor, mantenga redux simple como está ahora. Es un patrón. Los libros de cocina siempre surgirán alrededor de: 100:

@markerikson ¿Sería una buena idea comenzar un documento / hoja de cálculo para organizar estos pensamientos? Ya ha habido algunas ideas increíbles y solo han pasado 48 horas 🎉

Para mí, no recomendaría a la gente que use thunks o sagas. En su lugar, aprenda técnicas de inyección de dependencia en JavaScript.

Redux se vuelve más fácil una vez que lo trato como una base de datos simple:

  • Le digo a Redux el estado inicial y cómo una acción (evento) afecta el estado de la aplicación. (Como el esquema de la base de datos y los procedimientos almacenados).
  • Luego, Redux se encarga de administrarlo y notificar a los oyentes, y proporciona formas de inspeccionar y depurar el estado.

Para mí, eso es todo lo que Redux es para mí (no esperaría que una base de datos hiciera una llamada HTTP). Para I / O y cosas asincrónicas, lo realizo fuera de Redux. Esto hace que mi tienda Redux sea predecible. La firma de tipo es siempre store.dispatch(actionObject) . Sin funciones de envío y sin significado oculto dentro de la acción (por ejemplo, el envío de una acción no hará una llamada a la API).

@tannerlinsley : Sí, adelante.

Una desventaja para mí al comenzar esta discusión: ya tengo un montón de cosas en las que necesito trabajar y escribir. Gran parte es autoimpuesto, pero significa que no tengo tiempo suficiente para trabajar en algunos de los temas relacionados con Redux que me gustaría investigar, y mucho menos abordar cosas como una renovación importante de documentos o crear un nuevo conjunto de herramientas a partir de rasguño.

Definitivamente quiero estar involucrado en estos posibles esfuerzos, pero será necesario que otras personas se unan y trabajen juntas. (Últimas palabras famosas de todos los mantenedores de OSS ... :))

Redux se vuelve más fácil una vez que lo trato como una base de datos simple

¡Esto es lo que recomiendo!

  • Mantén tu tienda normalizada
  • Puede preparar vistas similares a datos. Haga esto con reductores dedicados , entonces no necesita reselect . Considerar.
  • Las acciones no deberían desencadenar otras acciones; esto puede parecer fácil. Pero es difícil si tienes ganchos componentDidMount . No sé cómo solucionar esto. Cambiar esto en la jerarquía no siempre es fácil

FWIW, he estado usando Redux con D3.js (sin React) y me ha ido bastante bien. Algunos ejemplos de esto se enumeran en el componente d3 .

Lo que más extraño de los enlaces de React Redux es connect . El punto que me interesaría más del esquema / visión anterior de @gaearon es "proporcionar implementaciones de mapStateToProps ".

Puede preparar vistas similares a datos. Haga esto con reductores dedicados; entonces no necesita volver a seleccionar. Considerar.

Sí, esto es un poco lo que hace Twitter en su tienda, al menos eso creo: tienen una rama entities que contiene identificadores habituales para mapas de datos y, por ejemplo, vista timeline , que es básicamente la fuente principal vea cuál contiene referencias de identificación a la rama de entidades, pero ya está calculado previamente.

Y eso es lo que estoy buscando en los próximos refactores, ya que volver a seleccionar listas altamente dinámicas es ... no demasiado eficiente;) el único inconveniente que veo es que terminas un poco con datos duplicados, y también la manipulación de actualizaciones y eliminaciones en la vista podría ser bastante engorroso a largo plazo, ya que necesita recordar a menudo alrededor de 2 lugares (o más).

@stefensuhat cuando intenté implementar Redux por mi cuenta, usé un bucle Promise para hacer posibles las acciones asíncronas. Puede consultarlo en https://github.com/iddan/delux

¡@gaearon está totalmente de acuerdo con tu lista! Hemos estado trabajando en un modelo redux siguiendo el 90% de la lista en la organización en la que estoy trabajando (también, siguiendo los principios de los patos). Es un lanzamiento anticipado en este momento, no está listo para publicarse.

¡Definitivamente me gustaría contribuir a esta buena idea!

@markerikson @tannerlinsley

En cuanto a la organización de estas ideas, sugiero que después de hacer la hoja de cálculo, cree problemas de Github en los repositorios apropiados para rastrear el desarrollo. Luego, debe comentar aquí con una lista de esos problemas.

Esto no garantiza que nada en particular se envíe con redux, pero le da a las personas interesadas en ese tema en particular la oportunidad de seguir la discusión y trabajar juntos para que esto suceda.

La carga de hacer realidad estas sugerencias recae en todos los que estamos interesados ​​en cada nueva característica o enfoque. Aunque Mark inició la discusión, estoy seguro de que nadie espera que lo implemente todo. :)

Sí, la lista de @gaearon es ideal, pero como algunas personas ya han mencionado, son muchas cosas. Cualquiera que intente abordarlo directamente se enfrentará a un derrumbe de bicicletas al olvido. Me encantaría ver que suceda de todos modos, pero creo que las piezas más pequeñas deben atacarse a la vez, en lugar de construir una capa completa en la parte superior (nuevamente presionando mi ejemplo de una tienda de inicio preconfigurada;))

Dicho esto, cuando / si alguien intenta atacar esa lista completa, también tenga en cuenta qué otras herramientas y marcos existen fuera de Redux, e incluso fuera de React. React / Redux tiene un interesante conjunto de beneficios sobre vanilla Flux, sobre MobX, sobre VueJS y su ecosistema, sobre Angular. Independientemente de lo que haga la comunidad, probablemente quiera concentrarse en algunos de estos beneficios (algunos de los cuales son parte de la lista de @gaearon ) y asegurarse de que cualquier capa que se construya en la parte superior no se vuelva totalmente redundante. Muchas cosas, como la depuración de viajes en el tiempo, los ecosistemas de middleware, etc., están disponibles en otros lugares.

Ejemplo que estoy inventando: puede ser tentador crear un módulo que te permita crear una función que actualice automáticamente un reductor generado automáticamente. Pero una vez que haces eso, replicas MobX, por lo que no es muy útil hacerlo.

@Phoenixmatrix sí, lo que quiero decir es que redux tiene middleware predeterminado, por lo que no necesitamos usar uno externo. 😄

Realmente no veo nada malo con la implementación actual de Redux. El texto estándar existe, pero realmente no es un gran problema si tiene un sistema de tipos.

Un problema importante para mí es que la gente no parece entender que estamos creando aplicaciones frontend que son mucho más complejas de lo que solían ser hace algunos años. Si estamos construyendo aplicaciones que son más grandes, más complejas, con equipos grandes, es normal para mí que la dificultad aumente significativamente, que surjan nuevos patrones, pero la gente rechaza esa dificultad.

No estoy diciendo que no deberíamos intentar simplificar las cosas o reducir el texto estándar, sino que la gente no debería comenzar a usar Redux y quejarse del texto estándar involucrado sin comprender las compensaciones que se realizan y ver el panorama general.

Cuando se creó Redux, muchas personas (incluido yo) intentaron construir esa cosa, y @gaearon obtuvo la mejor implementación e hizo un muy buen trabajo en herramientas / demostración. Inicialmente, (y también Flux) obtuvo mucha tracción, no solo por el viaje en el tiempo, sino también porque el concepto no era nuevo para muchas personas e inmediatamente se sentía natural.

La gente ve a Redux como un nuevo juguete brillante (que parece no ser tan fácil en la práctica). Sin embargo, nada en Redux es realmente nuevo, excepto el hecho de que alguien transfirió esos conceptos de una manera elegante a la interfaz. Los patrones de Redux y su ecosistema ya se utilizan en sistemas distribuidos, aplicaciones backend basadas en eventos, diseño impulsado por dominios, y las personas que tienen experiencia en estos entenderán Redux muy fácilmente.

Desafortunadamente, la gente quiere saltarse pasos y usar Redux sin saber nada sobre los patrones más generales involucrados. Personalmente, recomendaría a cualquiera que desee construir algo serio en Redux que tenga una experiencia mínima en sistemas distribuidos. Puede parecer extraño, pero creo que tener ese tipo de experiencia puede darte una ventaja muy importante en este momento y en los años venideros.

¿Qué estamos construyendo exactamente cuando construimos una aplicación frontend?

  • Construimos un miembro de un sistema distribuido
  • Ese miembro solo contiene un subconjunto de los datos del sistema más general
  • Ese miembro tiene capacidades bastante limitadas (almacenamiento, ancho de banda, estabilidad de la red ...)

Entonces, intentamos construir algo muy complejo. Tenemos limitaciones que son más difíciles de manejar que los desarrolladores de bases de datos, pero queremos que sea más simple, sin reutilizar el conocimiento previo de personas que realmente pensaron mucho en estos problemas durante muchos años. ¿No crees que la gente ya pensó en cómo estructurar el estado dentro de una base de datos? como consultarlo?

No estoy diciendo que no debamos ser pragmáticos, enviar aplicaciones hoy y cometer errores con nuestro conocimiento actual, sino más bien entender y reconocer que lo que estamos construyendo ya no es simple y requiere conocimientos adicionales. Redux podría ser un buen camino para obtener este conocimiento, y puede usarlo de una manera pragmática al principio, pero no subestime la cantidad de desarrollo de frontend que lo hará sentir incómodo en los próximos años.

Desafortunadamente, la gente quiere saltarse pasos y usar Redux sin saber nada sobre los patrones más generales involucrados.

Para bien o para mal, Redux esencialmente ha ganado la batalla por la gestión del estado de React. Con eso viene la capacidad de dar forma al ecosistema. Siempre habrá desarrolladores que solo quieran algo que funcione, y hay muchas aplicaciones más simples donde eso es todo lo que se necesita. O las personas continuarán usando otras capas de abstracción, o se les puede presentar los patrones generales correctos a través de una biblioteca simple.

Personalmente, recomendaría a cualquiera que desee construir algo serio en Redux que tenga una experiencia mínima en sistemas distribuidos. Puede parecer extraño, pero creo que tener ese tipo de experiencia puede darte una ventaja muy importante en este momento y en los años venideros.

Este es el quid de la cuestión. Redux como está funciona muy bien para las personas que lo entienden. Sin embargo, no es necesariamente algo malo simplificarlo. La mayoría de las personas ya no escriben código ensamblador, aunque comprenderlo normalmente le ayuda a escribir mejor código. No es ahí donde empieza la mayoría de la gente.

Muchos más comentarios buenos por todos lados. Aquí hay toneladas de ideas que podríamos y deberíamos explorar más a fondo.

Veamos si podemos empezar a pensar en algunas ideas potencialmente viables. Comenzaré lanzando un pequeño concepto básico:

Cree un nuevo paquete llamado, no sé, redux-starter o algo así. Ese paquete podría depender de redux-actions , redux-thunk y redux-logger , y tal vez un middleware basado en promesas. Proporcionaría una función con la firma function createReduxStore({reducers, middleware}) {} (basada en el comentario anterior de @Phoenixmatrix ). ¿Ni siquiera podría molestarse en aceptar middleware?

La función createReduxStore() se encargaría de manejar applyMiddleware y configurar la recarga en caliente para el reductor raíz, así como de configurar la extensión Redux DevTools. Si no se proporciona middleware, configuraría los incluidos de forma predeterminada. Esto puede parecer similar al código de configuración del servicio de la tienda en ember-redux o la función configureStore en mi aplicación de muestra "Project Mini-Mek" .

Esto al menos minimizaría la cantidad de configuración necesaria para comenzar y proporcionaría un conjunto modesto de funcionalidades útiles.

Sí, me gusta eso (bueno, no me gustan las acciones redux y los middlewares basados ​​en promesas para los usuarios más nuevos, pero dejaré que se diviertan con el descarte de bicicletas en ese). No me molestaría en aceptar middleware, simplemente createStarterStore (reductor).

Tal vez incluso reemplace combineReducer, por lo que simplemente puede hacer:

const store = createStarterStore({
   foo,
   bar,
   baz
});

donde foo bar baz son reductores.

Maldita sea. Me acabo de dar cuenta de que "una función de biblioteca que configura HMR para el reductor raíz" probablemente no funcionará, porque incluso si permitiéramos al usuario pasar la ruta a su archivo reductor raíz, uno o ambos module.hot.accept() API y require(path) paso de reimportación quieren rutas que sean analizables estáticamente en el momento de la compilación y no variables. (Creo que ... podría estar equivocado.) Oh, bueno.

Pero sí, createStarterStore() podría aceptar el reductor de raíz o el objeto de cortes.

Personalmente, recomendaría a cualquiera que desee construir algo serio en Redux que tenga una experiencia mínima en sistemas distribuidos. Puede parecer extraño, pero creo que tener ese tipo de experiencia puede darte una ventaja muy importante en este momento y en los años venideros.

@slorber Estoy de acuerdo contigo en esa parte.

Desafortunadamente, la gente quiere saltarse pasos y usar Redux sin saber nada sobre los patrones más generales involucrados.

Pero no realmente en este. Algunas personas conocen los patrones involucrados en Redux, y esta es precisamente la razón por la que eligieron usarlo. Querer usar algo simple (o al menos más simple) no significa necesariamente que el usuario no sea capaz de usar una implementación más difícil. Simplemente ahorra tiempo y esfuerzo.

En el lugar donde trabajo, hemos usado Redux durante un año y nos hemos encontrado copiando / pegando el mismo código (solo modificándolo un poco) para agregar nuevos recursos a la tienda, por lo que en algún momento sentimos la necesidad de implementar una capa encima de Redux, para abstraer este repetitivo repetitivo.
En mi opinión, esta idea no solo simplifica el uso de Redux, sino que también reduce el texto estándar de las partes más comunes (de la misma manera, react-redux reduce el texto estándar cuando se usa Redux junto con React).

Discusión muy interesante. Mis dos centavos como usuario de redux desde los primeros días:

Al principio, según recuerdo, redux se veía más como un protocolo o un conjunto de convenciones razonables que como un marco para crear aplicaciones. Esta austeridad es parte de por qué redux puede ser abrumador para la gente nueva y tedioso para escalar sin rodar sus propias abstracciones. Pero la forma simple en que eliminó el desorden de la gestión del estado en 2015 también es una razón por la que despegó, y el minimalismo ha permitido que marcos increíbles como Apollo se aprovechen del trabajo realizado para diferentes proyectos (especialmente herramientas de desarrollo) y brinden una forma familiar "bajar a un nivel inferior" en la gestión estatal cuando sea necesario.

Creo que está claro que, como una biblioteca redux de "bajo nivel", ha sido un gran éxito, y como un marco de trabajo rico en funciones para crear aplicaciones, aún no ha llegado a ese punto. Una cosa con la que hay que tener cuidado es que a medida que redux evoluciona, no rompe su función como "protocolo" estándar de la industria para proyectos como Apollo.

Con este fin, tal vez redux actual pueda convertirse en un paquete como redux-core , y redux sí mismo eleva el nivel de abstracción para ofrecer una forma recomendada de crear aplicaciones. Por supuesto, puede haber cualquier cantidad de alternativas de nivel superior a este redux (como Apollo, ¿o algo usando sagas?) Usando redux-core ...

Reafirmando las cosas para aclarar y enfatizar:

Cualquier trabajo fuera de este hilo no incluirá cambios importantes en la biblioteca existente de Redux :) Es totalmente posible una renovación de documentos, y puede haber algunos pequeños ajustes, pero el paquete redux permanecería como está.

Cualquier cosa como el paquete redux-starter que acabo de describir, o el enfoque "marco" -y que describió Dan, sería un nuevo paquete que depende de redux .

Voto que creamos el paquete como sugirió @markerikson . Una vez que tenemos una base de código, podemos comenzar a trabajar con api, fragmentos de código e ideas más detalladas. Entonces tendríamos un lugar para crear problemas para características específicas.

Puede usar Delux como iniciador (jk)

Como gran usuario de Jumpstate de @tannerlinsley (y ahora uno de los mantenedores), estoy increíblemente emocionado por esto. Mis razones para usar Jumpstate se describen de manera muy sucinta en la publicación original de

Una forma larga de decir: suena increíble, estoy dentro, no estoy seguro de cuánto puedo contribuir (lo intentaré) pero ciertamente tienes una animadora.

He usado Jumpstate para enseñar Redux varias veces y puedo decir con seguridad que ha acortado considerablemente la curva de aprendizaje. Pienso en Redux como HTTP y Jumpstate como fetch. Me encanta Redux y he escrito algunas cosas (ridículamente) complicadas con él, pero también sé que el 90% del caso es más que suficiente para enseñar la mayoría de las cosas.

Cuando lo piensas, este es un gran lugar para estar. Una de las principales quejas sobre el desarrollo de frontend y javascript en general es "la falta de bibliotecas estándar". La cosa es que esto es algo muy nuevo (TM) , poder desarrollar aplicaciones completas en el navegador. La presión finalmente está aumentando para necesitar bibliotecas estándar. Ahí es donde estamos ahora.

Re: Curva de aprendizaje, obstinación y abstracción:

Ajax parece ser un área donde los nuevos estudiantes se quedan atascados, ya sea que estén aprendiendo a usar thunks, sagas o epopeyas. Un área en la que no parecen tener mucha dificultad es la creación de acciones, ya que son simplemente objetos antiguos de Javascript, y tenemos la claridad adicional proporcionada por la especificación Flux Standard Actions. Esta línea de pensamiento me llevó a la pregunta: ¿por qué no desarrollar una acción Ajax estándar de flujo ?

P.ej

function fetchPosts(page) {
  return {
    type: 'FETCH_POSTS_REQUEST',
    // Ajax request setup
    ajax: {
      url: `/api/posts`,
      method: 'GET',
      data: { page },

      // Optional ajax meta attributes
      meta: {
        // Amount of time to debounce the execution of the request
        debounce: 400,
        // Amount of times to retry the request on failure
        retry: 2,
        // Amount of time before timing out
        timeout: 10000,  
        // The action type that cancels the request
        cancelType: 'CANCEL_FETCH_POSTS',
        // Strategy when multiple FETCH_POSTS_REQUESTs are in flight
        resolve: 'LATEST'
      }
    }
  };  
}

La acción ajax sería manejada por middleware (que reaccionaría a la tecla ajax en la acción).

He estado tratando de pensar en las razones por las que este enfoque sería una mala idea, pero todavía no he pensado en ningún factor decisivo.
Algunos beneficios en mi opinión:

  • una disminución dramática en la cantidad de acciones asíncronas requeridas en su aplicación promedio (ya que las acciones asíncronas relacionadas con ajax desaparecerían)
  • fácil de entender ya que solo estamos tratando con objetos antiguos simples de JavaScript
  • es declarativo, los detalles de implementación no son importantes
  • Las diferentes implementaciones se pueden intercambiar hacia adentro / hacia afuera sin roturas.
  • es Redux idiomático (el registro de acciones todavía tiene sentido, serializable, etc.)

Puedo escuchar a algunas personas invocando el argumento de la separación de preocupaciones, pero yo diría que es una extensión natural de lo que nuestras acciones de solicitud ajax ya están haciendo. Actualmente están configurando una acción con un contexto bastante claro, 'FETCH_POSTS_REQUEST' , pero con muy poco contexto para abstraer la implementación de la solicitud ajax. Dejando pocas opciones más que realizar manualmente la solicitud ajax en otro lugar.

Otra cosa que me viene a la mente es el encadenamiento de acciones asíncronas que he visto en algunos documentos. No hemos tenido la necesidad de encadenar solicitudes de esta manera, por lo que no estoy seguro de cuán ampliamente utilizado es este encadenamiento, pero mi intuición es que estaría fuera del alcance de lo que propongo aquí (y tal vez no caen dentro del caso de uso del 90% mencionado en esta discusión).

En conclusión, parece muy posible que una abstracción como esta ayude a facilitar la curva de aprendizaje y la cantidad de código necesaria para escribir aplicaciones comunes de Redux. ¿Alguien tiene alguna idea sobre este enfoque? ¿Algún factor decisivo en el que pueda pensar? @markerikson @gaearon

Estado de la técnica: redux-axios-middleware

Muchas cosas están sucediendo en este hilo.

Respecto a la discusión sobre la complejidad de Redux. Personalmente, no estoy de acuerdo con la gente que se queja de que Redux es complicado y detallado. Es una compensación que hace cuando opta por una biblioteca de bajo nivel basada en arquitecturas Flux & Elm. En la página de inicio de Redux se indica que es posible que no lo necesite. Pero todavía tenemos gente quejándose de que es complicado.

Redux se encuentra como está. Por suerte, el equipo central es consciente de que tiene funciones completas y no está dispuesto a cambiarlo. Las abstracciones construidas sobre él son impresionantes y cada una de ellas tiene su propio caso de uso. Esto es lo que esperaría de una biblioteca de bajo nivel buena y bien diseñada.

Veo el problema no en Redux en sí, sino en la falta de una forma progresiva y funcional de aprenderlo. Como algunos mencionaron, React tuvo el mismo problema y create-react-app fue la solución.

Tal vez ese ni siquiera sea el problema, ya que hay recursos increíbles para eso (es decir, la serie de cabeza de

De todos modos, esto no es de lo que se trata este hilo.

@markerikson Personalmente estoy redux-starter .

_Me encantaría un nombre más genial_: pegado_out_tongue:

El texto estándar requerido para producir muchas acciones es prácticamente el único inconveniente que veo con redux.

Es de muy bajo nivel, pero creo que eso es genial. Esa es una de las razones por las que prefiero el paradigma de estilo Redux sobre MobX, por ejemplo, aunque entiendo su utilidad y usaría MobX. Pero solo sería feliz haciendo eso ahora que entiendo Redux. Debido a que Redux (o el patrón de Redux en general), los datos no van particularmente "detrás de escena". Generalmente, dondequiera que se esté procesando el código, usted lo escribió, y si no, puede entenderlo (si se ha tomado el tiempo para aprender, más sobre eso más adelante).

La cuestión es que, cuando estaba aprendiendo por primera vez sobre Redux, era mucho para entender, pero también era simple. Algo puede ser a la vez difícil y simple. Sin embargo, debido a eso, pensé: "¡Vaya, este concepto es tan lógico! Tiene tanto sentido que apuesto a que podría hacerlo yo mismo". Entonces, para mi primer proyecto, en lugar de usar el paquete Redux, hice mi propia pequeña tienda Redux.

Hacer eso no solo me ayudó a comprender el concepto de Redux, ¡sino que también aumentó mucho mi comprensión del Javascript en sí mismo! (Esto es desde la perspectiva de alguien que no sabía casi nada sobre conceptos de programación funcional antes de esto, por lo que su millaje puede variar). El concepto de Redux es realmente bastante brillante en su simplicidad, pero también increíblemente poderoso.

Creo que la cuestión es que, dado que Redux es tan popular, es, uhh, "la moda de las palabras" puede distraer a los recién llegados de lo bien que funciona en Javascript. Así que su mentalidad puede ser "ok, tengo React, Redux, etc, etc, ahora voy a ser un programador increíble y hacer una gran aplicación". No es que haya nada malo en eso. Pero pueden centrarse en solo querer usar una nueva herramienta brillante para acelerar el proceso de desarrollo, sin comprender qué hace que la herramienta funcione.

Una vez que se entiende el concepto, resulta muy fácil hacer que Redux (o cualquier patrón similar a Redux) haga todo tipo de cosas. Me gusta por la misma razón que me gusta React sobre otras herramientas (aún geniales) como Angular. _Es solo Javascript._ ¡Así es como funciona Javascript!
Si el texto estándar necesario se puede reducir a través de algún paradigma, sería genial, pero creo que es un pequeño precio a pagar por un powaaaaaa de unlimiteddd.

En mi opinión, todo esto "la verbosidad es una compensación" es simplemente masoquismo; la verbosidad no está al servicio de nada, es un sacrificio que haces para usar Redux en absoluto. No culpo a Redux o javascript, solo quiero señalar que esto no es una complejidad esencial. Elm gestiona todo lo que Redux logra en menos líneas y un código más simple.

Entonces escribimos mecánicamente el texto estándar. Jumpstate y similares facilitan la vida, pero existen límites para lo que puede hacer en tiempo de ejecución, y con mecanografiado / flujo, jumpstate no ayuda mucho. Pero codegen es difícil y nadie quiere agregar una cosa más a su ya sobrecargado sistema de compilación.

Si pudiera tener algo como el código de Elm que se tradujo al idiomático Redux ... Quédate quieto mi corazón palpitante.

Estas son algunas de mis ideas, espero no repetir comentarios anteriores:

Los creadores de acciones se pueden utilizar como tipos de acciones.

actions.js

export function increase() {}

reducer.js

import { increase } from './actions.js';
export default handleActions({
    [increase]: (state) => state + 1
}, 0);

Como las funciones tienen referencias únicas, podemos tratarlas como identificadores de acciones. No es compatible con FSA, pero ahorra mucho código y evita errores.

Las acciones se pueden enviar de forma asincrónica

async function a() {

}
async function b() {
}
store.dispatch(a());
store.dispatch(b()); // b() will be dispatched after a() resolves

De esa manera, los creadores de acciones pueden ser funciones asíncronas y, sin embargo, distribuirse una tras otra. Como lo veo en muchas situaciones, la gente no necesitará usar soluciones basadas en middleware y esto ahorrará mucho código repetitivo.
Este concepto es implementado por una fábrica de promesas en Delux.

redux === texto estándar

https://github.com/Emilios1995/redux-create-module

pero creo que esta función puede salvarle la vida por completo.

Vale la pena diferenciar entre dos conjuntos diferentes de ideas que se desarrollan en este hilo:

  • un marco basado en redux de "servicio completo"
  • características adicionales en redux core

Estoy de acuerdo con @markerikson en que redux core no debería convertirse en un marco en sí mismo, y entiendo por qué uno querría mantener redux-thunk y react-redux en paquetes separados. Sin embargo, creo que hay espacio y precedente para nuevas "funciones auxiliares" en el núcleo de redux.

Redux tiene una superficie de API bastante pequeña: createStore , applyMiddleware , combineReducers , bindActionCreators y compose . Pero la mayoría de estas son funciones de conveniencia. Solo createStore es estrictamente necesario para que Redux funcione. ¿Por qué algunos de estos pertenecen al núcleo?

  • applyMiddleware crea una interfaz simplificada para almacenar potenciadores. Pero lo que es más importante, applyMiddleware admite la interfaz _interface_ del middleware como una forma estándar de agregar efectos a las tiendas redux. El ecosistema de middleware es posible porque applyMiddleware tiene una interfaz relativamente simple y permite a los usuarios ejecutar muchos middleware a la vez.

  • combineReducers proporciona una forma conveniente de composición reductora. Está lejos de ser la única forma de componer reductores, pero ciertamente es uno de los patrones más útiles. Pero su presencia en el núcleo de redux significa que no solo es común sino también ubicuo. Cada aplicación Redux no trivial que he encontrado usa combineReducers para crear el reductor de raíz. La otra cara de esto es que debido a que combineReducers es la única forma de composición reductora que viene con Redux, muchos usuarios parecen creer que es la única forma de composición reductora que existe.

  • bindActionCreators reduce parte del texto estándar en torno a las acciones de despacho. Pero perversamente, bindActionCreators también es indirectamente responsable de parte de la reputación de Redux como modelo estándar. Esto se debe a que la mera existencia de bindActionCreators fomenta el uso de creadores de acciones. Esto es particularmente visible cuando se compara la prevalencia de los creadores de acciones (que están "respaldados" por bindActionCreators ) frente a los selectores (que están documentados pero no tienen una función central equivalente). He visto muchas bases de código que usan react-redux donde mapStateToProps siempre son selectores "a medida", pero mapDispatchToProps siempre es un mapa de objetos de creadores de acciones previamente escritos.

Ninguno de estos es esencial para la funcionalidad de Redux, pero todos son esenciales para su usabilidad. Ninguna de estas funciones limita la flexibilidad inherente de Redux, pero al convertir patrones comunes en funciones invocables, hacen que las elecciones sean menos abrumadoras. Y cada una de estas funciones auxiliares plantea más preguntas:

  • Si el middleware es una simplificación de los mejoradores de la tienda, ¿existen otras simplificaciones que podrían ser de gran utilidad?
  • ¿Qué otras formas de composición reductora podrían implementarse en lugar de simplemente documentarse? ¿ Objetos reductores ? ¿ Reductores dependientes ? ¿ Composición lineal ?
  • ¿La integración de la reselección conduciría a las personas a crear y componer selectores donde no lo habían hecho antes? ¿Sería esto un resultado neto positivo?

Incluso si las respuestas a todas estas preguntas son negativas, creo que nos perjudicamos a nosotros mismos y a la comunidad al negarnos a considerar siquiera sus premisas.

@modernserf : Primero, gracias por sus comentarios, así como por sus otros pensamientos recientes sobre Redux. Todos son extremadamente valiosos e informativos, y probablemente debería ser una lectura obligatoria para cualquier otra persona en este hilo. Entonces, los vincularé aquí:

Es muy interesante que debas mencionarlos, debido a la historia involucrada (que acabo de pasar mucho tiempo investigando para mi publicación El Tao de Redux, Parte 1 - Implementación e intención . En particular, redux-thunk fue originalmente integrado en Redux , y react-redux solo se separó más tarde también .

Tiene razón en que esas utilidades codifican ciertos patrones de uso. Dicho esto, esas utilidades se incluyen porque codifican los patrones de uso _intendidos_: composición de reductores de segmentos, una canalización de middleware para el comportamiento asíncrono y otro comportamiento centralizado, y creadores de acciones vinculadas para simplificar el proceso de envío de acciones desde componentes (en particular, pasar funciones alrededor a los componentes secundarios). De manera similar, aunque Reselect no está en el núcleo, Dan fomentó explícitamente su creación .

Así que sí, cualquiera "podría" haberlos escrito, pero al incorporarlos, hemos impulsado a las personas a usar esas herramientas específicas de formas específicas. Definitivamente de acuerdo en eso.

Según sus últimas tres preguntas:

  • Supongo que se podría decir que el middleware es "una simplificación de los potenciadores de la tienda", aunque no creo que eso les haga justicia. Más bien, es un potenciador de la tienda para un propósito muy especializado. En cuanto a otros trabajos relacionados con los potenciadores de tienda: Dan ha dicho que la parte principal del núcleo de Redux que todavía le gustaría modificar se relaciona con la forma en que se inicializan los potenciadores. En realidad, hay dos RP "en competencia" para cambiar la implementación del potenciador de tienda que han estado abiertos durante mucho tiempo: la versión de @acdlite en # 1706 y la versión de @jimbolla en # 2214. También es interesante notar que Jim elaboró una lista de todos los potenciadores de tiendas conocidos para ayudar a analizar cómo la comunidad los está utilizando realmente. Sé que la propuesta de Jim estaba destinada a ayudar a los autores de potenciadores a simplificar los comportamientos que se ven comúnmente. Entonces, esa es una dirección que podría explorarse más a fondo.
  • Definitivamente hay muchos otros patrones para la composición y estructura de los reductores. No estoy seguro de qué podríamos hacer exactamente en lo que respecta a los reductores "dependientes", ya que ese es un caso de uso mucho más específico y parece ser bastante específico de la aplicación. En una nota relacionada, durante mucho tiempo, Dan había cerrado cualquier RP que propusiera agregar algún tipo de tercer argumento a combineReducers (y ha habido un _mucho_ de ellos), pero finalmente permitió que # 1768 avanzara por un tiempo. Ese PR también se ha estancado.
  • El caso de uso más común para los selectores parece ser extraer directamente bits de estado y pasarlos como accesorios con nombre. También tenemos un PR abierto para React-Redux para agregar una sintaxis abreviada de objeto para mapState , y hemos tenido numerosas solicitudes para eso, aunque puede hacer lo mismo con createStructuredSelector .

Como documenté en esa publicación de "Tao of Redux", los objetivos declarados eran mantener la API central de Redux lo más mínima posible y fomentar un ecosistema por encima de ella . Además, al principio del desarrollo de Redux, Andrew hizo un comentario sobre la intención de "bendecir" ciertos complementos :

Como dijo una vez gaearon, (no recuerdo dónde ... probablemente Slack) pretendemos ser como las bibliotecas Koa of Flux. Eventualmente, una vez que la comunidad esté más madura, el plan es mantener una colección de complementos y extensiones "bendecidos", posiblemente bajo una organización GitHub de reduxjs.

Anteriormente, había propuesto algún tipo de lib de abstracción de "configuración fácil de Redux", o algo así. ¿Sería suficiente algo así, o al menos esa lista de complementos "bendecidos", en la línea que estás pensando? (Y, de hecho, tú también lo hiciste en el primer comentario de este hilo). Si no, ¿alguna propuesta o idea adicional?

Eventualmente, una vez que la comunidad esté más madura, el plan es mantener una colección de complementos y extensiones "bendecidos", posiblemente bajo una organización GitHub de reduxjs.

Esto es lo que haría también, aunque probablemente iría un paso más allá: reestructuraría el proyecto en un monorepo, donde el paquete actual redux convierte en algo así como @redux/core , bendito bibliotecas como reselect y redux-action se incorporan al repositorio y al espacio de nombres, y el paquete redux sí mismo simplemente reexporta todos estos paquetes en un solo espacio de nombres.

Ese _sort of_ satisface la restricción de no modificar redux core. Además, la versión extendida sería un superconjunto estricto y, por lo tanto, compatible con versiones anteriores del núcleo. Las nuevas funciones serían meramente opcionales y no tendrían acceso especial al estado privado. En lo que respecta a "hinchazón", cada una de estas bibliotecas es pequeña para empezar, y están escritas de tal manera que sería trivial sacudirlas.

También tenemos un PR abierto para React-Redux para agregar una sintaxis abreviada de objeto para mapState, y hemos recibido numerosas solicitudes para eso, aunque puede hacer lo mismo con createStructuredSelector de Reselect.

Creo que esto debería decirte algo.

La estructura de monorepo que estoy sugiriendo es básicamente la estructura utilizada por Lodash. Ahora, Lodash es una biblioteca interesante para modelar: es una enorme colección de funciones, muchas de las cuales son triviales de implementar usted mismo. Casi todas las funciones en lodash podrían ser más flexibles como una "receta" - groupBy es realmente un _patrón_ después de todo; ¿Quiénes somos para decir en qué estructuras de datos lo usas?

Y cada función lodash también está disponible en su propia biblioteca _a la carte_. No hay ningún beneficio _funcional_ para import { groupBy } from "lodash" más de import groupBy from "group-by" . ¿Por qué debería tener que lidiar con el temblor de árboles cuando puedo instalar lo que necesito?

Pero la experiencia de usar Lodash es fundamentalmente diferente a la de usar recetas o nanotecnologías. Sabes que si estás haciendo algo con una matriz y tienes la sensación de que te estás repitiendo, probablemente haya una función Lodash para hacerlo. No necesita buscar una receta, no necesita instalar nada; es probable que ni siquiera necesite agregar otra línea de importación al archivo. Solo está eliminando la más mínima cantidad de fricción, pero nuestros días están llenos de momentos como este y se acumulan.

Espero que no le importe que agregue mis propios 2 centavos, desde una perspectiva diferente.

Las escuelas de pensamiento CQRS , Event Sourcing y, en última instancia, Domain Driven Design son los mayores antepasados ​​que nos llevaron a Flux y Redux . Si bien estas influencias se citan ocasionalmente , Redux y sus herramientas descendientes tomaron la mayor parte de su terminología API de las implementaciones de Flux y Flux que eran populares en ese momento. Esto está bien, pero creo que estamos perdiendo la oportunidad de sacar provecho de la exposición existente que los desarrolladores pueden haber tenido a esas ideas.

Para dar dos ejemplos de la diferencia: en la mayoría de las discusiones sobre abastecimiento de eventos que he visto, las acciones de Redux se denominarían eventos . Los ActionCreators de Redux se denominarían Comandos . Creo que hay algo de claridad y semántica adicional que viene gratis con esta terminología también. Los eventos son datos serializables y registrables. Los eventos describen lo que sucedió en tiempo pasado. Los eventos se pueden reproducir. Los eventos no se pueden anular el registro. Los comandos tienen un estado de ánimo imperativo. Los comandos desencadenan eventos .

Sospecho que Event Sourcing como patrones arquitectónicos ganará popularidad durante la próxima década, y creo que Redux podría ganar algo de usabilidad, claridad y facilidad de uso al alinear la API y la discusión más de cerca con la comunidad en general.

Creo que esta discusión ya fue golpeada hasta la muerte: https://github.com/reactjs/redux/issues/351

¡Oh, no estaba al tanto de eso, gracias! : +1:

Parece que el número 351 se cerró porque en ese momento no se podía realizar ninguna acción. Si estamos en una coyuntura en la que estamos reconsiderando las decisiones de API y el lenguaje que usamos, este parece un momento apropiado para resurgir la idea, para mí.

Puedo ser más concreto.

Esta es mi idea de cómo se vería una API inspirada en los modismos de Event Sourcing :

Conceptos

  • Flujo de eventos observable
  • Event Stream tiene un conjunto bien escrito de eventos compatibles
  • Envío de comandos al flujo de eventos
  • Uno o más clientes consume el flujo de eventos

API

import { createEventStream, createProjection } from 'redux';

// Initialize the event stream separately from the store.  This becomes the one
// true source of truth for your application.
const eventStream = createEventStream({
  // Commands are the only thing that we want to couple to the eventStream.  The 
  // set of events which may end up in an eventStream should be easy to predict.
  //
  // A definition like this supports static analysis inference well for 
  // consumers that can leverage it.
  increment: () => ({ type: 'INCREMENT' }),
  decrement: () => ({ type: 'DECREMENT' }),
});

// Multiple stores with disjoint or overlapping data can be used to consume the 
// same event stream.
const store = createProjection(eventStream, reducer, init);
const adminStore = createProjection(eventStream, adminReducer, init);

// We don't need a jargon term ("Middleware"), or a dedicated hook to handle 
// async anymore.  We just register more subscribers to the eventStream.
eventStream.subscribe(myCustomMiddleWare);
eventStream.subscribe(sendEventsToAnalytics);
eventStream.subscribe(logEventsForPlayback);

// Calls to commands can be wrapped with React Providers or container components 
// in the same way that Redux currently does.  They can also be called directly.
eventStream.increment();

@ajhyndman : si bien aprecio la sugerencia y la discusión, el cobertizo para bicicletas ha sido pintado por completo y el caballo ha huido del granero (para mezclar completamente las metáforas). Dan optó por utilizar terminología Flux en lugar de términos CQRS / ES, y no hay planes para cambiar las API principales o los términos utilizados para los conceptos de Redux.

(Además, aunque no tengo estadísticas para corroborar esto, supongo que en este punto hay más personas familiarizadas con el uso de Redux de "acciones" y "creadores de acciones" que con la terminología CQRS / ES, al menos dentro de la comunidad JS. )

Definitivamente tengo la impresión de que esta conversación se ha tenido antes y hay un fuerte deseo de no volver a abrirla. 😄 No presionaré mucho más aquí. (Me interesaría leer o continuar esta conversación en otro lugar, si hay un mejor punto de contacto).

Por supuesto, también tiene razón en que existe un factor de atrincheramiento, y cambiar toda la superficie y la terminología de la API sería costoso en este momento.

Todavía diría que hay una oportunidad para que las comunidades de Event Sourcing y Redux aprendan unas de otras.

  • ¿Qué posibles abstracciones podrían crearse que simplifiquen el proceso de aprendizaje y uso, pero sin ocultar realmente Redux (y con suerte proporcionarían una ruta de migración / aprendizaje a Redux "base")?

Incluso sin tomar prestada la terminología o cambiar la API, creo que podemos encontrar beneficios. Por ejemplo, he tenido éxito al presentar a la gente a Redux al describir una tienda como "un contenedor de estado en el que currentState es una" función pura de "(se deriva o se reduce de) una lista de solo anexar (o una secuencia) de Acciones ".

Mirando más hacia el futuro, creo que es completamente posible implementar y abstraer una infraestructura de servidor similar a redux (ver: Apache Samza y algunos de los otros trabajos del equipo de ingeniería de LinkedIn). Si aspiramos a eso, ¡también debería ser posible utilizar abstracciones similares para la gestión del estado del cliente y del servidor! Si podemos lograr eso, ¿por qué no una tienda Redux persistente e isomórfica?

Cualquier concepto en el que las comunidades de infraestructura y JavaScript puedan combinarse o mapear fácilmente entre ellos, más rápidamente espero que estas oportunidades se hagan evidentes y más expresivas sean las abstracciones.

¡Supongo que me estoy entusiasmando un poco con algunas de estas ideas! Espero que me perdonen por la palabra basurero.

Nota al margen: parece posible crear una API contenedora similar a una secuencia de eventos para Redux que implemente la superficie que sugerí anteriormente.

https://github.com/ajhyndman/redux-event-stream

@ajhyndman Creo que el envoltorio es el camino correcto para ir con tu idea allí 👍

Relacionado con el trabajo de ingeniería de samza y linkedin que mencionaste, si otros no han leído / visto la maravillosa charla Volviendo la base de datos de adentro hacia afuera con Apache Samza, ¡ entonces busca una hora para hacerlo en algún momento! Creo que vi a Dan mencionarlo en un archivo Léame o en un tweet en algún momento. Esta charla cambió para siempre la forma de ver las bases de datos y la administración del estado y es un primo idealológico muy cercano de redux.

¡Ese video es asombroso! En realidad, también es el segundo elemento de la lista de agradecimientos en el archivo README del repositorio de redux .

¡Hola a todos!

Sin ser consciente de la existencia de este hilo, he desarrollado una biblioteca que de alguna manera es una respuesta directa a las preguntas originales de @markerikson y elimina la mayoría de las cosas de la lista de @gaearon .

La biblioteca se llama Kea :

screen shot 2017-08-06 at 13 10 03

Es una abstracción sobre redux, redux-saga y reselect. Excepto por el pegamento que los une, Kea no pretende crear nada nuevo y expone a los creadores y reductores de acciones redux en bruto, sagas de saga redux en bruto y selectores de reselección sin procesar según sea necesario. No inventa un concepto nuevo.

Kea admite muchos modos de operación diferentes: puede usarlo de forma independiente, conectado a los componentes de React, alineados arriba de los componentes de React o incluso conectado dinámicamente a los componentes de React donde la entrada a los selectores depende de los accesorios del componente de React.

Personalmente, lo uso con dos grandes aplicaciones: un mercado para lecciones privadas y un gran software de seguimiento de flotas. Además, conozco personas que han creado sus propias aplicaciones con él. Debido a que fue tan útil para nosotros, dediqué un tiempo considerable a limpiarlo y escribir documentación .

Para mí, esta biblioteca siempre ha reducido en gran medida el texto estándar, sin dejar de ser fiel al núcleo de redux en sí.

De todos modos, basta de hablar, aquí hay un código. Este es un ejemplo de lo que yo llamo "kea en línea", donde la lógica se adjunta directamente a su componente. Este modo es ideal para cuando recién está comenzando o como una alternativa al setState React.

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { kea } from 'kea'

@kea({
  actions: () => ({
    increment: (amount) => ({ amount }),
    decrement: (amount) => ({ amount })
  }),

  reducers: ({ actions }) => ({
    counter: [0, PropTypes.number, {
      [actions.increment]: (state, payload) => state + payload.amount,
      [actions.decrement]: (state, payload) => state - payload.amount
    }]
  }),

  selectors: ({ selectors }) => ({
    doubleCounter: [
      () => [selectors.counter],
      (counter) => counter * 2,
      PropTypes.number
    ]
  })
})
export default class Counter extends Component {
  render () {
    const { counter, doubleCounter } = this.props
    const { increment, decrement } = this.actions

    return (
      <div className='kea-counter'>
        Count: {counter}<br />
        Doublecount: {doubleCounter}<br />
        <button onClick={() => increment(1)}>Increment</button>
        <button onClick={() => decrement(1)}>Decrement</button>
      </div>
    )
  }
}

En caso de que su aplicación crezca y más lugares necesiten acceso a las acciones increment y decrement o counter prop, puede dividir su código así:

// counter-logic.js
import PropTypes from 'prop-types'
import { kea } from 'kea'

export default kea({
  actions: () => ({
    increment: (amount) => ({ amount }),
    decrement: (amount) => ({ amount })
  }),

  reducers: ({ actions }) => ({
    counter: [0, PropTypes.number, {
      [actions.increment]: (state, payload) => state + payload.amount,
      [actions.decrement]: (state, payload) => state - payload.amount
    }]
  }),

  selectors: ({ selectors }) => ({
    doubleCounter: [
      () => [selectors.counter],
      (counter) => counter * 2,
      PropTypes.number
    ]
  })
})
// index.js
import React, { Component } from 'react'
import { connect } from 'kea'

import counterLogic from './counter-logic'

@connect({
  actions: [
    counterLogic, [
      'increment',
      'decrement'
    ]
  ],
  props: [
    counterLogic, [
      'counter',
      'doubleCounter'
    ]
  ]
})
export default class Counter extends Component {
  render () {
    const { counter, doubleCounter } = this.props
    const { increment, decrement } = this.actions

    return (
      <div className='kea-counter'>
        Count: {counter}<br />
        Doublecount: {doubleCounter}<br />
        <button onClick={() => increment(1)}>Increment</button>
        <button onClick={() => decrement(1)}>Decrement</button>
      </div>
    )
  }
}

Pruébelo y lea los documentos para obtener más información sobre los efectos secundarios a través de redux-saga y otras funciones que puede utilizar.

Los comentarios para Kea han sido abrumadoramente positivos hasta ahora, citando un número : "¡Más personas deberían usar KeaJS para hacer del mundo de redux un lugar mejor! 👍" :)

¡Gracias por su tiempo y por leer hasta aquí! :)

¡Se ve bien! aunque no me gusten las cuerdas mágicas 'increment'

¿Esta discusión avanzó en otro lugar? ¿Es Kea el resultado más correcto que se acepta generalmente?

@lucfranken : no, la discusión se apagó.

Si está buscando una abstracción de nivel superior sobre Redux, entonces Kea es probablemente una buena opción. Si está buscando un "paquete de inicio de Redux" que simplifique el proceso de configuración de la tienda, es posible que tenga que buscar algunos. Sé que he visto algunas cosas así en la naturaleza, pero no tenemos ninguna biblioteca oficial como esa en este momento.

Tirando mi sombrero al ring aquí. Así es como abordo este problema: https://github.com/HenrikJoreteg/redux-bundler

Personalmente, creo que es una gran simplificación y reducción del texto estándar.

Así es como he estado construyendo todo lo que construyo recientemente.

Oye, en mi empresa acabamos de abrir una biblioteca que administra la capa de red y elimina una gran cantidad de texto estándar de Redux. Ha demostrado ser un éxito para nosotros, pero pruébelo usted mismo: https://github.com/Brigad/redux-rest-easy/ (artículo mediano: https://engineering.brigad.co/introducing-redux-rest-easy -6e9a91af4f59)

1_327nnvo3cuaqc-dsqpoq7w

aquí está mi enfoque para reducir el texto estándar de redux
image

https://github.com/zhDmitry/restate

Como necrogación muy tardía del hilo, hace un tiempo pedí comentarios en Twitter sobre lo que significa "repetitivo" para la gente:

https://twitter.com/acemarke/status/969040835508604929

¡Regreso del necrohilo!

Según mi edición del primer comentario en este hilo, las ideas discutidas aquí se han convertido en nuestro paquete Redux-Starter-Kit . ¡Pruébelo y vea cuánto puede ayudar a simplificar su uso de Redux!

¿Fue útil esta página
0 / 5 - 0 calificaciones