No React podemos trabalhar com formulários de maneira padrão, onde a submissão produz uma navegação para outra página, e da maneira "React", onde teremos controle dos componentes para controle dos dados.
Componentes controlados
Por padrão, os componentes html "input", "textarea" e "select" mantém o próprio estado de acordo com as entradas que o usuário realiza, como vimos, com o React fazemos essa atualização apenas por meio do "setState", mas para trabalhar com formulários trabalharemos com uma mescla dessas duas ideias, fazendo com que o estado controlado pelo React seja nossa verdadeira fonte de dados, nossa fonte da verdade.
Para isso, basicamente precisaremos fazer com que o componente "input" tenha como valor uma das propriedades do estado e sempre que o valor do "input" for alterado atualizaremos esse estado:
import React from 'react';
class FormularioNome extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Nome: ' + this.state.value);
event.preventDefault();
}
render() {
return (
form onSubmit={this.handleSubmit}>
fieldset>
legend>Formulário nome:legend>
label>
Nome:
input type="text" value={this.state.value}
onChange={this.handleChange} />
label>
input type="submit" value="Enviar" />
fieldset>
form>
);
}
}
export default FormularioNome
No exemplo acima Temos um componente, "FormularioNome", que trabalha com um "input" que recebe valores referentes a um nome, perceba o evento "onchange" que utiliza a função "handleChange" para manter o estado atualizado.
textarea
No React o "textarea" também trabalha com a propriedade "value", dessa forma seu uso é idêntico a um "input" comum:
import React from 'react';
class FormularioTexto extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Texto: ' + this.state.value);
event.preventDefault();
}
render() {
return (
form onSubmit={this.handleSubmit}>
fieldset>
legend>Formulário texto:legend>
label>
Texto:
textarea value={this.state.value} onChange={this.handleChange} />
label>
input type="submit" value="Enviar" />
fieldset>
form>
);
}
}
export default FormularioTexto
No exemplo anterior temos o componente "FormularioTexto", onde, a exemplo do que vimos com o "input", temos o evento "onchange" que utiliza a função "handleChange" para manter o estado atualizado, alterando o conteúdo do "textarea" de acordo com o digitado pelo usuário.
select
Com o componente "select" já temos valores definidos (lista suspensa), logo o que se altera é o item selecionado, e no React também determinamos essa seleção com o estado:
import React from 'react';
class FormularioFormaPagamento extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'dinheiro'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Forma pagamento: ' + this.state.value);
event.preventDefault();
}
render() {
return (
form onSubmit={this.handleSubmit}>
fieldset>
legend>Formulário forma pagamento:legend>
label>
Select:
select value={this.state.value} onChange={this.handleChange}>
option value="debito">Cartão de débitooption>
option value="credito">Cartão de créditooption>
option value="cheque">Chequeoption>
option value="dinheiro">Dinheirooption>
select>
label>
input type="submit" value="Enviar" />
fieldset>
form>
);
}
}
export default FormularioFormaPagamento
No código acima, temos como exemplo o componente "FormularioFormaPagamento", onde, a exemplo do que vimos com o "input", temos o evento "onchange" que utiliza a função "handleChange" para manter o estado atualizado, alterando o item selecionado de acordo com o escolhido pelo usuário.
checkbox
Com o componente "checkbox" determinamos a seleção de uma opção, logo o que se altera é a indicação de item selecionado, e no React também determinamos essa seleção com o estado:
import React from 'react';
class FormularioConfirmarContrato extends React.Component {
constructor(props) {
super(props);
this.state = {value: true};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.checked});
}
handleSubmit(event) {
alert('Confirma contrato: ' + this.state.value);
event.preventDefault();
}
render() {
return (
form onSubmit={this.handleSubmit}>
fieldset>
legend>Formulário confirmar contrato:legend>
label>
CheckBox:
input type="checkbox" checked={this.state.value}
onChange={this.handleChange} />
label>
input type="submit" value="Enviar" />
fieldset>
form>
);
}
}
export default FormularioConfirmarContrato
No código acima, temos como exemplo o componente "FormularioConfirmarContrato", onde, a exemplo do que vimos com o "input", temos o evento "onchange" que utiliza a função "handleChange" para manter o estado atualizado, alterando o item selecionado de acordo com o escolhido pelo usuário.
radio
Com o componente "radio" já temos valores definidos, logo o que se altera é o item selecionado, e no React também determinamos essa seleção com o estado:
import React from 'react';
class FormularioSexoCliente extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Sexo cliente: ' + this.state.value);
event.preventDefault();
}
render() {
return (
form onSubmit={this.handleSubmit}>
fieldset>
legend>Formulário confirmar sexo cliente:legend>
label>
Masculino:
input type="radio" name="sexo-cliente" value="masculino"
checked={this.state.value === 'masculino'}
onChange={this.handleChange} />
label>
label>
Feminino:
input type="radio" name="sexo-cliente" value="feminino"
checked={this.state.value === 'feminino'}
onChange={this.handleChange} />
label>
input type="submit" value="Enviar" />
fieldset>
form>
);
}
}
export default FormularioSexoCliente
No código acima, temos como exemplo o componente "FormularioSexoCliente", onde, a exemplo do que vimos com o "input", temos o evento "onchange" que utiliza a função "handleChange" para manter o estado atualizado, alterando o item selecionado de acordo com o escolhido pelo usuário.
Múltiplos inputs
Nos exemplos anteriores cada formulário tinha apenas um componente, mas bem sabemos que isso não é o comum, por padrão sempre teremos vários componentes em um mesmo formulário, logo precisamos de uma forma de controlar o estado de "n" componentes e no React conseguiremos isso determinado o componente a ter o estado alterado pela propriedade "name", recuperando ela do objeto alterado:
import React from 'react';
class FormularioCompra extends React.Component {
constructor(props) {
super(props);
this.state = {
nome: '',
contrato: false,
endereco: '',
pagamento: 'dinheiro'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSubmit(event) {
alert(
'Nome:' + this.state.nome +
'\nSexo:' + this.state.sexo +
'\nEndereço: ' + this.state.endereco +
'\nPagamento: ' + this.state.pagamento +
'\nContrato:' + this.state.contrato
);
event.preventDefault();
}
render() {
return (
form onSubmit={this.handleSubmit}>
fieldset>
legend>Formulário compra:legend>
label>
Nome cliente:
input name="nome" value={this.state.nome}
onChange={this.handleChange} />
label>
label>
Masculino:
input type="radio" name="sexo" value="masculino"
checked={this.state.sexo === 'masculino'}
onChange={this.handleChange} />
label>
label>
Feminino:
input type="radio" name="sexo" value="feminino"
checked={this.state.sexo === 'feminino'}
onChange={this.handleChange} />
label>
label>
Endereço entrega:
textarea name="endereco" value={this.state.endereco}
onChange={this.handleChange} />
label>
label>
Forma pagamento:
select value={this.state.pagamento} onChange={this.handleChange}>
option value="debito">Cartão de débitooption>
option value="credito">Cartão de créditooption>
option value="cheque">Chequeoption>
option value="dinheiro">Dinheirooption>
select>
label>
label>
Li e entendi o contrato:
input type="checkbox" name="contrato"
checked={this.state.contrato}
onChange={this.handleChange} />
label>
input type="submit" value="Enviar" />
fieldset>
form>
);
}
}
export default FormularioCompra
Em nosso último exemplo, componente "FormularioCompra" temos um "input" para o nome do cliente, um "radio" para determinar o sexo do cliente, um "textarea" para o endereço do cliente, um "select" para definir a forma de pagamento e um "checkbox" para confirmar o contrato.
file input
O "file input" é para envio de arquivos locais para manipulação por Javascript (File API) ou para envio a servidores e por ter um valor somente leitura não pode ter seu estado controlado pelo React.
Em breve veremos alguns pontos avançados e dentre eles como trabalhar com arquivos.
Os exemplos podem ser encontrados aqui.
Os exemplos podem ser encontrados aqui.