Estou começando com React.js e quero fazer um formulário simples, mas na documentação, encontrei duas maneiras de fazê-lo.
O primeiro está usando Refs :
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = React.findDOMNode(this.refs.author).value.trim();
var text = React.findDOMNode(this.refs.text).value.trim();
if (!text || !author) {
return;
}
// TODO: send request to the server
React.findDOMNode(this.refs.author).value = '';
React.findDOMNode(this.refs.text).value = '';
return;
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
E o segundo está usando o estado dentro do componente React:
var TodoTextInput = React.createClass({
getInitialState: function() {
return {
value: this.props.value || ''
};
},
render: function() /*object*/ {
return (
<input className={this.props.className}
id={this.props.id}
placeholder={this.props.placeholder}
onBlur={this._save}
value={this.state.value}
/>
);
},
_save: function() {
this.props.onSave(this.state.value);
this.setState({value: ''
});
});
Não consigo ver os prós e os contras das duas alternativas, se houver alguma. Obrigado.
Respostas:
A versão curta: evite refs.
Eles são ruins para a manutenção e perdem muito da simplicidade que a renderização do modelo WYSIWYG oferece.
Você tem um formulário. Você precisa adicionar um botão que redefina o formulário.
Você tem um campo de número CCV em uma entrada e alguns outros campos em seu aplicativo que são números. Agora você precisa obrigar o usuário a inserir apenas números.
Eh, esquece, o PM quer que façamos apenas uma sombra de caixa vermelha se for inválida.
Precisamos devolver o controle aos pais. Os dados agora estão em adereços e precisamos reagir às mudanças.
sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js
As pessoas pensam que os árbitros são "mais fáceis" do que mantê-los no estado. Isso pode ser verdade nos primeiros 20 minutos, não é verdade na minha experiência depois disso. Coloque-se em posição de dizer "Sim, farei isso em 5 minutos" em vez de "Claro, vou reescrever alguns componentes".
fonte
React.findDOMNode(this.refs.foo)
. Se você mudar, por exemplo,this.refs.foo.props.bar
nada acontecerá.<input onChange={this.handleChange} value={this.state.foo} />
alterou para<input onChange={this.props.handleChange} value={this.props.foo} />
, ou modificou sua (s) função (ões) handleChange para chamar o (s) retorno (ões) de chamada em props. De qualquer forma, são algumas pequenas mudanças óbvias.input
campo onde cada um mantém seu próprio estado é ideal. Em algum ponto, precisamos reconciliar esses vários estados independentes com algum modelo maior. Talvez tenhamos um salvamento automático em um cronômetro, ou apenas economizamos.componentWillUnmount
É aqui que eu acho orefs
ideal, durante a reconciliação, extraímos ostate
valor de cada umref
, e ninguém é mais sábio. Eu concordo na maioria dos casosstate
é a resposta, mas com um grande número deinputs
, utilizar umrefs
padrão adequado é um benefício de desempenhoEu vi algumas pessoas citarem a resposta acima como uma razão para "nunca usar refs" e eu quero dar minha opinião (assim como alguns outros desenvolvedores do React com quem conversei).
O sentimento "não use refs" está correto ao falar sobre como usá-los para instâncias de componente. Ou seja, você não deve usar refs como uma forma de obter instâncias de componentes e chamar métodos neles. Esta é a maneira incorreta de usar os árbitros e é quando os árbitros vão para o sul rapidamente.
A maneira correta (e muito útil) de usar refs é quando você os usa para obter algum valor do DOM. Por exemplo, se você tem um campo de entrada anexando um ref a essa entrada, então pegar o valor mais tarde por meio do ref está ótimo. Sem essa maneira, você precisa passar por um processo razoavelmente orquestrado para manter seu campo de entrada atualizado com o estado local ou com o armazenamento de fluxo - o que parece desnecessário.
Edição de 2019: Olá amigos do futuro. Além do que mencionei há alguns anos ^, com React Hooks, refs também são uma ótima maneira de manter o controle de dados entre renderizações e não estão limitados a apenas capturar nós DOM.
fonte
refs
e obtenha o valor do estado. Na verdade, parece um padrão muito bom.TL; DR De modo geral,
refs
vá contra a filosofia declarativa do React , então você deve usá-los como último recurso. Usestate / props
sempre que possível.Para entender onde você usa
refs
vsstate / props
, vamos dar uma olhada em alguns dos princípios de design que o React segue.Documentação por React sobre
refs
Princípios de design de Per React sobre escotilhas de fuga
O que significa que a equipe do React sugere evitar
refs
e usarstate / props
para qualquer coisa que possa ser feita de forma reativa / declarativa.@Tyler McGinnis deu uma resposta muito boa , afirmando também que
Embora você possa fazer isso, estará trabalhando contra a filosofia do React. Se você tem valor em uma entrada, certamente vem de
state / props
. Para manter o código consistente e previsível, você também deve se limitar astate / props
isso. Eu reconheço o fato de querefs
às vezes te dá a solução mais rápida, então se você fizer uma prova de conceito, rápido e sujo é aceitável.Isso nos deixa com vários casos de uso concretos para
refs
fonte
Esta postagem é antiga.
Vou compartilhar minha pequena experiência em um caso sobre esse assunto.
Eu estava trabalhando em um grande componente (414 linhas) com muitas entradas 'dinâmicas' e muitos dados em cache envolvidos. (Não estou trabalhando sozinho na página e meus sentidos me dizem que a estrutura do código provavelmente poderia ser dividida melhor, mas não é o ponto (bem, poderia ser, mas estou lidando com isso)
Trabalhei primeiro com o estado para lidar com os valores das entradas:
e, claro, nas entradas:
A renderização era tão pesada que a alteração da entrada era instável como **** (não tente manter a tecla pressionada, o texto só apareceria após uma pausa)
Eu tinha certeza de que poderia evitar isso usando refs.
acabou assim:
e nas entradas:
[bem, no meu caso, a entrada era Material-UI TextField, então era:
]
Graças a isso, não há renegociação, a entrada é suave, a funcionalidade funciona da mesma forma. Isso vai economizar ciclos e cálculos, portanto, energia também. Faça isso pela terra x)
Minha conclusão: useRef para o valor das entradas pode até ser necessário.
fonte