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
, SENDING
y 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.state
por supuesto, junto con los valores de campo.
Si estas fueran vistas de Backbone, habría extraído una clase base llamada, FormView
pero 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 FeedbackWidget
y JoinWidget
en su estado actual . Tienen una estructura similar, un beginSend
mé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
FormWidget
yInputWidget
. Sin embargo, abandoné este enfoque a la mitad porque quería un mejor control sobre los mensajes generadosinput
y su estado.Dos artículos que más me ayudaron:
Resultó que solo necesitaba escribir dos mixins (diferentes):
ValidationMixin
yFormMixin
.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.errors
matriz para que pueda resaltar los campos correspondientes.Fuente ( esencia )
Uso
ValidationMixin
tiene tres métodos:validate
,hasError
yresetError
.Espera que la clase defina el
validators
objeto, similar apropTypes
:Cuando el usuario presiona el botón de envío, llamo
validate
. Una llamada avalidate
ejecutará cada validador y se completaráthis.state.errors
con una matriz que contiene claves de las propiedades que fallaron en la validación.En mi
render
método, utilizohasError
para generar la clase CSS correcta para los campos. Cuando el usuario pone el foco dentro del campo, llamoresetError
para eliminar el resaltado de error hasta la próximavalidate
llamada.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:,
sendRequest
que 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
,isFormSubmitting
yisFormSubmitted
. También proporciona un método para dar inicio a la solicitud:submitForm
. Puede llamarlo desde elonClick
controlador de botones de formulario .fuente
FormInput
que habla con su dueño víaformLink
.formLink
es comovalueLink
, y se devuelve desdeFormMixin
'slinkValidatedState(name, validator)
método.FormInput
obtiene su valor deformLink.value
y llamaformLink.requestBlur
yformLink.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} ... />
done
a 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 (
componentDidMount
etc.). 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
LinkedStateMixin
código para que la sintaxis sea:¿Existe alguna gran diferencia?
fuente