Existem três respostas aqui, dependendo da versão do React com a qual você é forçado a trabalhar e se deseja usar ganchos.
Primeiras coisas primeiro:
É importante entender como Reagir obras, para que possa fazer as coisas corretamente (Protip: é é super- pena que atravessa a Reagir exercício tutorial no site Reagir É bem escrito, e abrange todos os fundamentos de uma forma que realmente explica como fazer. coisas). "Corretamente" aqui significa que você está escrevendo uma interface de aplicativo que é renderizada em um navegador; todo o trabalho da interface acontece no React, não no "com o qual você está acostumado se estiver escrevendo uma página da web" (é por isso que os aplicativos do React são "aplicativos", não "páginas da web").
Os aplicativos de reação são renderizados com base em duas coisas:
- as propriedades do componente, conforme declaradas por qualquer pai, cria uma instância desse componente, que o pai pode modificar ao longo do seu ciclo de vida, e
- o próprio estado interno do componente, que pode ser modificado ao longo de seu próprio ciclo de vida.
O que você não está fazendo expressamente quando usa o React está gerando elementos HTML e depois os utiliza: quando você diz ao React para usar um <input>
, por exemplo, você não está criando um elemento de entrada HTML, está dizendo ao React para criar um objeto de entrada React que é renderizado como um elemento de entrada HTML e cuja manipulação de eventos examina, mas não é controlada pelos eventos de entrada do elemento HTML.
Ao usar o React, o que você está fazendo é gerar elementos da interface do usuário do aplicativo que apresentam dados ao usuário (geralmente manipuláveis), com a interação do usuário alterando o estado do Componente, o que pode fazer com que o re-renderizador de parte da interface do aplicativo reflita o novo estado. Nesse modelo, o estado é sempre a autoridade final, não "qualquer biblioteca da interface do usuário usada para renderizá-lo", que na Web é o DOM do navegador. O DOM é quase uma reflexão tardia nesse modelo de programação: é apenas a estrutura específica da interface do usuário que o React está usando.
Portanto, no caso de um elemento de entrada, a lógica é:
- Você digita o elemento de entrada,
- nada acontece com o seu elemento de entrada ainda, o evento foi interceptado pelo React e eliminado imediatamente ,
- Reagir encaminha o evento para a função que você configurou para manipulação de eventos,
- essa função pode agendar uma atualização de estado,
- caso isso aconteça, o React executa essa atualização de estado (de forma assíncrona!) e acionará uma
render
chamada após a atualização, mas somente se a atualização do estado alterou o estado.
- somente depois que essa renderização ocorrer, a interface do usuário mostrará que você "digitou uma letra".
Tudo isso acontece em questão de milissegundos, se não menos, então parece que você digitou o elemento de entrada da mesma maneira que costumava "apenas usar um elemento de entrada em uma página", mas não é absolutamente isso que aconteceu.
Então, com isso dito, sobre como obter valores de elementos no React:
Reagir 15 e abaixo, com ES5
Para fazer as coisas corretamente, seu componente possui um valor de estado, que é mostrado por meio de um campo de entrada, e podemos atualizá-lo fazendo com que esse elemento da interface do usuário envie eventos de mudança de volta para o componente:
var Component = React.createClass({
getInitialState: function() {
return {
inputValue: ''
};
},
render: function() {
return (
//...
<input value={this.state.inputValue} onChange={this.updateInputValue}/>
//...
);
},
updateInputValue: function(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Portanto, dizemos Reagir a usar a updateInputValue
função para lidar com a interação do usuário, uso setState
para agendar a atualização de estado, eo fato de que render
torneiras em this.state.inputValue
meios que, quando se renderiza novamente depois de atualizar o estado, o usuário verá o texto de atualização com base no que eles digitado.
adendo baseado em comentários
Dado que as entradas da interface do usuário representam valores de estado (considere o que acontece se um usuário fechar sua guia no meio do caminho e a guia for restaurada. Todos os valores preenchidos devem ser restaurados? Se sim, esse é o estado). Isso pode fazer você sentir que um formulário grande precisa de dezenas ou até cem formulários de entrada, mas o React é sobre como modelar sua interface do usuário de maneira sustentável: você não possui 100 campos de entrada independentes, possui grupos de entradas relacionadas e, portanto, captura cada agrupe em um componente e, em seguida, crie seu formulário "mestre" como uma coleção de grupos.
MyForm:
render:
<PersonalData/>
<AppPreferences/>
<ThirdParty/>
...
Isso também é muito mais fácil de manter do que um componente de formulário único gigante. Divida os grupos em Componentes com manutenção de estado, onde cada componente é responsável apenas pelo rastreamento de alguns campos de entrada por vez.
Você também pode achar que é "um aborrecimento" escrever todo esse código, mas isso é uma falsa economia: os desenvolvedores que não são você, incluindo o futuro, se beneficiam muito ao ver todas essas entradas conectadas explicitamente, porque facilita muito o rastreamento dos caminhos de código. No entanto, você sempre pode otimizar. Por exemplo, você pode escrever um vinculador de estado
MyComponent = React.createClass({
getInitialState() {
return {
firstName: this.props.firstName || "",
lastName: this.props.lastName || ""
...: ...
...
}
},
componentWillMount() {
Object.keys(this.state).forEach(n => {
let fn = n + 'Changed';
this[fn] = evt => {
let update = {};
update[n] = evt.target.value;
this.setState(update);
});
});
},
render: function() {
return Object.keys(this.state).map(n => {
<input
key={n}
type="text"
value={this.state[n]}
onChange={this[n + 'Changed']}/>
});
}
});
Obviamente, existem versões aprimoradas disso, então acesse https://npmjs.com e procure uma solução de vinculação de estado React que você mais goste. O código-fonte aberto é principalmente descobrir o que os outros já fizeram e usá-lo em vez de escrever tudo do zero.
Reagir 16 (e 15,5 transitório) e JS 'moderno'
A partir do React 16 (e iniciação suave com 15.5), a createClass
chamada não é mais suportada e a sintaxe da classe precisa ser usada. Isso muda duas coisas: a sintaxe óbvia da classe, mas também a this
ligação de contexto que createClass
pode ser executada "de graça"; portanto, para garantir que as coisas continuem funcionando, verifique se você está usando a notação "seta gorda" para this
preservar funções anônimas em onWhatever
manipuladores, como o onChange
que usamos no código aqui:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
};
}
render() {
return (
//...
<input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
//...
);
},
updateInputValue(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Você também pode ter visto pessoas usarem bind
no construtor para todas as suas funções de manipulação de eventos, assim:
constructor(props) {
super(props);
this.handler = this.handler.bind(this);
...
}
render() {
return (
...
<element onclick={this.handler}/>
...
);
}
Não faça isso.
Quase sempre que você está usando bind
, o proverbial "você está fazendo errado" se aplica. Sua classe já define o protótipo do objeto e, portanto, já define o contexto da instância. Não coloque bind
por cima disso; use o encaminhamento normal de eventos em vez de duplicar todas as suas chamadas de função no construtor, porque essa duplicação aumenta sua superfície de bugs e torna muito mais difícil rastrear erros, pois o problema pode estar no seu construtor e não no local onde você chama o código. Além de sobrecarregar os outros com quem você (tem ou escolhe) trabalhar.
Sim, eu sei que os documentos de reação dizem que está tudo bem. Não é, não faça.
Reagir 16.8, usando componentes de função com ganchos
A partir do React 16.8, o componente de função (isto é, literalmente, apenas uma função que usa algum props
argumento pode ser usado como se fosse uma instância de uma classe de componente, sem nunca escrever uma classe) também pode receber um estado, através do uso de hooks .
Se você não precisar de código de classe completo, e uma função de instância única será necessária, agora você poderá usar o useState
gancho para obter uma variável de estado única e sua função de atualização, que funciona aproximadamente da mesma forma que os exemplos acima, exceto sem a setState
chamada de função:
import { useState } from 'react';
function myFunctionalComponentFunction() {
const [input, setInput] = useState(''); // '' is the initial state value
return (
<div>
<label>Please specify:</label>
<input value={input} onInput={e => setInput(e.target.value)}/>
</div>
);
}
Anteriormente, a distinção não oficial entre classes e componentes de função era "componentes de função não têm estado", então não podemos mais nos esconder por trás disso: a diferença entre componentes de função e componentes de classe pode ser encontrada espalhada por várias páginas muito bem - documentação de reação escrita (nenhuma explicação de atalho para uma interpretação conveniente para você!), que você deve ler para saber o que está fazendo e, assim, saber se você escolheu a melhor solução (o que isso significa para você) para se programar fora de um problema que você está tendo.
this.onSubmit.bind(this);