used - ¿Hay algún lugar para OOP en redux?
redux observable angular 6 (3)
Esta pregunta está un poco basada en la opinión, pero concentrémonos en los puntos centrales.
No hay contradicción entre la programación funcional y la programación orientada a objetos. Solo necesitas usar los mismos patrones de programación. No hay ningún problema en usar clases (con herencia) en la programación funcional, si las mantiene inmutables.
Para demostrar mi punto, la popular biblioteca Immutable.js que es utilizada por muchas personas para mantener el estado en redux se compone de clases . Y esas clases tienen herencia (por ejemplo, OrderedSet extends Set
).
También tenga en cuenta que la mayoría de los componentes React
son clases y también usan herencia ( ... extends React.Component
).
He estado usando prácticas de programación orientada a objetos durante 25 años e intenté avanzar hacia la programación funcional durante los últimos 5 años, pero mi mente siempre se orienta hacia la POO cuando intento hacer algo complejo y, especialmente ahora que ES6 es compatible Sintaxis de OOP, esa es la forma natural para que construya cosas.
Ahora estoy aprendiendo a Redux y comprendo ( ¿cómo poner métodos en los objetos en estado de Redux? ) Que es un no-no poner instancias de clase en sus reductores; y el método recomendado para computar sobre el estado del reductor simple es mediante el uso de selectores (por ejemplo, a través de reselección). Y, por supuesto, React recomienda la composición sobre la herencia ( https://facebook.github.io/react/docs/composition-vs-inheritance.html , React redux oop classes ).
Pero, ¿hay algún lugar en el ecosistema React / Redux para objetos de clase con métodos y herencia?
Supongo que, para responder a mi propia pregunta, las clases de OOP fomentan la adición de propiedades de datos y operaciones sobre los datos en el mismo lugar, lo cual es bueno para la legibilidad, pero no encaja bien con las funciones puras y los datos inmutables.
Si iba a utilizar la POO, ¿tendría que rechazar la idea de que mis instancias persistan y mantengan el estado por un período de tiempo? ¿Como, cada vez que quiero usar uno, lo instalo a partir de los datos de la tienda, uso los métodos que deseo y los descarto? Eso podría obviar gran parte del ímpetu de usar clases de POO. Pero si mantengo las instancias cerca, tendré dolores de cabeza manteniéndolos sincronizados con la tienda.
Entonces, ¿es la respuesta usar siempre los selectores cuando estoy tentado a usar métodos y siempre usar la composición cuando estoy tentado a usar la herencia? Específicamente, me refiero a la hora de almacenar y manipular datos almacenados en una tienda Redux para su uso en los componentes React. Y, si es así, ¿dónde debería encajar? ¿Conectado a los selectores? ¿Inmediatamente desechable como sugerí?
Agregar mi caso de uso para mayor claridad: Mis datos son básicamente un gráfico enorme: muchos objetos con muchas propiedades y muchas relaciones entre objetos. Es de solo lectura, pero complejo. Mis objetos se llaman "conceptos".
Antes de tomar la decisión (probablemente estúpida) de migrar a Redux, usé clases para estructurar y representar conceptos, conjuntos de conceptos y relaciones entre conceptos. Mis clases incluían lógica api asíncrona para obtener conjuntos de conceptos, información sobre cada concepto e información sobre otros conceptos con los que cada concepto está relacionado. Si el usuario elige profundizar, las clases buscarán recursivamente e instanciarán nuevos conjuntos de conceptos. La documentación de Redux recomienda estructuras planas y normalizadas para datos anidados ( http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html ) que probablemente sea más prudente para el almacenamiento, pero mi modelo OOP fue bueno para atravesar secciones de gráfico y esas cosas. Me resulta difícil envolver mi cabeza usando selectores y un estado inmutable que podría involucrar el anidamiento, potencialmente con ciclos, o la necesidad de realizar llamadas asíncronas para obtener más datos.
Estoy usando exitosamente https://redux-observable.js.org/ para las cosas de la API.
Tal vez la respuesta de @Sulthan sea correcta: debería sentirme libre de usar técnicas OOP en mi aplicación Redux. Pero todavía parece extraño. No puedo mantener mis objetos alrededor porque si la tienda cambia (se buscan más datos, por ejemplo), mis objetos pueden quedar obsoletos. Si mis objetos están anidados pero mi tienda está normalizada, los crearé una instancia (de los selectores) cuando los necesite y me aseguraré de no guardarlos ...
La respuesta es que es posible pero muy desanimado y no idiomático.
React se basa en las clases y la herencia de un solo nivel de React.Component
para implementar componentes con estado con ciclos de vida, pero oficialmente no se React.Component
hacer más niveles de herencia en los componentes.
Redux se basa en principios de programación funcional. Por diversos motivos, se recomienda que mantenga su estado como objetos y matrices JS simples y que acceda / manipule utilizando funciones simples.
Ciertamente, he visto muchas bibliotecas que intentaron agregar una capa OOP encima de Redux (como las clases cuyos métodos se convierten en creadores y reductores de acciones). Esos trabajos , pero definitivamente van en contra del espíritu general de Redux.
En realidad uso una biblioteca llamada Redux-ORM , que le permite definir clases de modelos que actúan como una fachada sobre los objetos JS sin formato en su tienda. Sin embargo, a diferencia de muchas de las otras bibliotecas que he visto, funciona con Redux en lugar de intentar cambiar el comportamiento de Redux. Comenté cómo funciona Redux-ORM, cómo lo uso y por qué sigue siendo razonablemente idiomático, en las publicaciones de mi blog Practical Redux, Parte 1: Principios básicos de Redux-ORM y Práctica Redux, Parte 2: Conceptos y técnicas de Redux-ORM . En general, es una excelente herramienta para ayudar a administrar las relaciones y los datos normalizados en su tienda Redux.
Por último, actualmente estoy trabajando en una publicación de blog que tratará las limitaciones técnicas reales que requiere Redux (y por qué), en comparación con su intención de usar Redux, en comparación con cómo es posible usar Redux. Espero tener eso en la próxima semana, así que eche un vistazo a http://blog.isquaredsoftware.com .
Responderé a mi propia pregunta describiendo lo que terminé haciendo, tan imperfecto como es.
Primero, en lugar de la sintaxis de clase ES6 normal, comencé a usar stampit , que es más feo que las clases de ES6, pero mucho más flexible.
Principalmente, sin embargo, mis objetos complejos existen en dos formas:
- objetos JS llanos para la tienda
- Instancias de clase (realmente selladas) por conveniencia y poder de usar métodos de instancia.
Utilizo una convención de poner un punto de puntuación delante de todas las referencias a los objetos planos. Mi "solución" es mala y mala por muchas razones, pero creo que intentar usar selectores para todo sería peor. Si tiene curiosidad, aquí está el lugar en mi código donde "inflo" los objetos de mi almacén en instancias: https://github.com/Sigfried/vocab-pop/blob/localstorage/src/ducks/conceptSet.js#L292
ACTUALIZAR
Convertir los POJO de estado de redux en instancias de clase (regular o stampit) es una idea terrible y alguien debería haberme detenido hace mucho tiempo.
Probablemente debería haber aceptado la respuesta de @ markerikson, y tal vez valga la pena ver la cuestión de Redux-ORM, pero solo quería decir definitivamente, NO HAGO LO QUE HAGO. (Siempre pienso que soy tan inteligente al llenar los "huecos" de las tecnologías que estoy aprendiendo con hacks inteligentes) y luego paso meses dolorosos limpiando el lío una vez que entiendo por qué esa tecnología no incluyó mi hack en el primer lugar.)
Otra actualización
De componer software: una introducción :
Lo que no haremos es decir que la programación funcional es mejor que la programación orientada a objetos, o que debe elegir una sobre la otra. OOP vs FP es una falsa dicotomía. Todas las aplicaciones JavaScript reales que he visto en los últimos años mezclan ampliamente FP y OOP.
Parece que hay buenas maneras de pensar acerca de la combinación de PF y POO, y, sin duda, utilizará algunas clases y composiciones inmutables sin mucha herencia. Esta serie sobre composición se parece a lo que necesitaba aprender.