Estou começando a usar o Facebook React em um projeto de Backbone e até agora está indo muito bem.
No entanto, notei alguma duplicação se infiltrando em meu código React.
Por exemplo, tenho vários widgets semelhantes a formulários com estados como INITIAL
, SENDING
e SENT
. Quando um botão é pressionado, o formulário precisa ser validado, uma solicitação é feita e o estado é atualizado. O estado é mantido dentro do React this.state
, é claro, junto com os valores dos campos.
Se fossem visualizações do Backbone, eu teria extraído uma classe base chamada, FormView
mas minha impressão era que o React não endossa nem apóia a criação de subclasses para compartilhar a lógica da visualização (corrija-me se estiver errado).
Eu vi duas abordagens para reutilização de código no React:
- Mixins (como LinkedStateMixin que acompanha o React);
- Componentes do contêiner (como react-infinite-scroll ).
Estou correto que mixins e containers são preferidos à herança no React? Esta é uma decisão de design deliberada? Faria mais sentido usar um mixin ou um componente de contêiner para meu exemplo de “widget de formulário” do segundo parágrafo?
Aqui está uma essência com FeedbackWidget
e JoinWidget
em seu estado atual . Eles têm uma estrutura semelhante, beginSend
método semelhante e ambos precisarão de algum suporte de validação (ainda não existe).
fonte
Respostas:
No início, tentei usar subcomponentes para isso e extrair
FormWidget
eInputWidget
. No entanto, abandonei essa abordagem no meio do caminho porque queria um melhor controle sobre osinput
s gerados e seu estado.Dois artigos que mais me ajudaram:
Acontece que eu só precisava escrever dois mixins (diferentes):
ValidationMixin
eFormMixin
.Veja como eu os separei.
ValidationMixin
O mixin de validação adiciona métodos de conveniência para executar suas funções de validador em algumas das propriedades de seu estado e armazenar propriedades "com erro" em um
state.errors
array para que você possa destacar os campos correspondentes.Fonte ( essência )
Uso
ValidationMixin
tem três métodos:validate
,hasError
eresetError
.Ele espera que a classe defina o
validators
objeto, semelhante apropTypes
:Quando o usuário pressiona o botão de envio, eu ligo
validate
. Uma chamada paravalidate
irá executar cada validador e preencherthis.state.errors
com uma matriz que contém as chaves das propriedades que falharam na validação.No meu
render
método, eu usohasError
para gerar classe CSS correta para campos. Quando o usuário coloca o foco dentro do campo, eu chamoresetError
para remover o destaque do erro até a próximavalidate
chamada.FormMixin
O mixin de formulários controla o estado do formulário (editável, submetido, enviado). Você pode usá-lo para desabilitar entradas e botões enquanto a solicitação está sendo enviada e para atualizar sua visualização de acordo com o envio.
Fonte ( essência )
Uso
Ele espera que o componente forneça um método:
sendRequest
que deve retornar uma promessa do Bluebird. (É trivial modificá-lo para funcionar com Q ou outra biblioteca de promessa.)Ele fornece métodos de conveniência, como
isFormEditable
,isFormSubmitting
eisFormSubmitted
. Ele também fornece um método para lançar o pedido:submitForm
. Você pode chamá-lo a partir doonClick
manipulador dos botões do formulário .fonte
FormInput
que falar com seu dono viaformLink
.formLink
é comovalueLink
, e é devolvido a partirFormMixin
dolinkValidatedState(name, validator)
método.FormInput
obtém seu valor deformLink.value
e chamaformLink.requestBlur
eformLink.requestFocus
- eles causam a validação emFormMixin
. Finalmente, para personalizar o componente real que está sendo usado para entrada, posso passá-lo paraFormInput
:<FormInput component={React.DOM.textarea} ... />
done
bluebird e o código funcionará como está no Q (ou promessas nativas) - é claro que o bluebird é melhor. Observe também que a sintaxe mudou no React desde a resposta.Estou construindo um SPA com React (em produção há 1 ano), e quase nunca uso mixins.
O único caso de uso que tenho atualmente para mixins é quando você deseja compartilhar o comportamento que usa os métodos de ciclo de vida do React (
componentDidMount
etc). Este problema é resolvido pelos Componentes de Ordem Superior que Dan Abramov fala em seu link (ou usando a herança de classe ES6).Mixins também são frequentemente usados em frameworks, para tornar a API do framework disponível para todos os componentes, usando o recurso de contexto "oculto" do React. Isso não será mais necessário com a herança de classe ES6.
Na maioria das outras vezes, os mixins são usados, mas não são realmente necessários e podem ser substituídos por facilitadores por simples ajudantes.
Por exemplo:
Você pode refatorar facilmente o
LinkedStateMixin
código para que a sintaxe seja:Existe alguma grande diferença?
fonte