Estoy empezando a usar Facebook React en un proyecto de Backbone y hasta ahora me va muy bien.
Sin embargo, noté algunas duplicaciones en mi código de React.
Por ejemplo, tengo varios widgets en forma de formulario con estados como INITIAL, SENDINGy SENT. Cuando se presiona un botón, el formulario debe validarse, se realiza una solicitud y luego se actualiza el estado. El estado se mantiene dentro de React, this.statepor supuesto, junto con los valores de campo.
Si estas fueran vistas de Backbone, habría extraído una clase base llamada, FormViewpero mi impresión fue que React no respalda ni admite subclases para compartir la lógica de la vista (corríjame si me equivoco).
He visto dos enfoques para la reutilización de código en React:
- Mixins (como LinkedStateMixin que se envía con React);
- Componentes del contenedor (como react-infinite-scroll ).
¿Tengo razón en que se prefieren los mixins y los contenedores a la herencia en React? ¿Es esta una decisión de diseño deliberada? ¿Tendría más sentido utilizar un componente mixin o contenedor para mi ejemplo de "widget de formulario" del segundo párrafo?
Aquí hay una esencia con FeedbackWidgety JoinWidgeten su estado actual . Tienen una estructura similar, un beginSendmétodo similar y ambos necesitarán algún soporte de validación (todavía no existe).
fuente

Respuestas:
Al principio, traté de usar subcomponentes para esto y extraer
FormWidgetyInputWidget. Sin embargo, abandoné este enfoque a la mitad porque quería un mejor control sobre los mensajes generadosinputy su estado.Dos artículos que más me ayudaron:
Resultó que solo necesitaba escribir dos mixins (diferentes):
ValidationMixinyFormMixin.Así es como los separé.
ValidaciónMixin
Validation mixin agrega métodos convenientes para ejecutar sus funciones de validación en algunas de las propiedades de su estado y almacenar propiedades "con error" en una
state.errorsmatriz para que pueda resaltar los campos correspondientes.Fuente ( esencia )
Uso
ValidationMixintiene tres métodos:validate,hasErroryresetError.Espera que la clase defina el
validatorsobjeto, similar apropTypes:Cuando el usuario presiona el botón de envío, llamo
validate. Una llamada avalidateejecutará cada validador y se completaráthis.state.errorscon una matriz que contiene claves de las propiedades que fallaron en la validación.En mi
rendermétodo, utilizohasErrorpara generar la clase CSS correcta para los campos. Cuando el usuario pone el foco dentro del campo, llamoresetErrorpara eliminar el resaltado de error hasta la próximavalidatellamada.FormMixin
Form mixin maneja el estado del formulario (editable, envío, enviado). Puede usarlo para deshabilitar entradas y botones mientras se envía la solicitud, y para actualizar su vista en consecuencia cuando se envía.
Fuente ( esencia )
Uso
Espera que el componente proporcione un método:,
sendRequestque debería devolver una promesa Bluebird. (Es trivial modificarlo para que funcione con Q u otra biblioteca de promesas).Proporciona métodos de conveniencia como
isFormEditable,isFormSubmittingyisFormSubmitted. También proporciona un método para dar inicio a la solicitud:submitForm. Puede llamarlo desde elonClickcontrolador de botones de formulario .fuente
FormInputque habla con su dueño víaformLink.formLinkes comovalueLink, y se devuelve desdeFormMixin'slinkValidatedState(name, validator)método.FormInputobtiene su valor deformLink.valuey llamaformLink.requestBluryformLink.requestFocus—causan validación enFormMixin. Finalmente, para personalizar el componente real que se utiliza para la entrada, puedo pasarlo aFormInput:<FormInput component={React.DOM.textarea} ... />donea bluebird y el código funcionará como está en Q (o promesas nativas); por supuesto, bluebird es mejor. También tenga en cuenta que la sintaxis cambió en React desde la respuesta.Estoy construyendo un SPA con React (en producción desde 1 año) y casi nunca uso mixins.
El único caso de uso que tengo actualmente para mixins es cuando desea compartir un comportamiento que usa los métodos del ciclo de vida de React (
componentDidMountetc.). Este problema se resuelve con los componentes de orden superior que Dan Abramov habla en su enlace (o mediante el uso de la herencia de clases ES6).Los mixins también se utilizan a menudo en marcos, para hacer que la API del marco esté disponible para todos los componentes, mediante el uso de la función de contexto "oculta" de React. Esto tampoco será necesario con la herencia de clases ES6.
La mayoría de las otras veces, se usan mixins, pero en realidad no son necesarios y podrían reemplazarse más fácilmente con ayudantes simples.
Por ejemplo:
Puede refactorizar muy fácilmente el
LinkedStateMixincódigo para que la sintaxis sea:¿Existe alguna gran diferencia?
fuente