Hoje continuamos a discussão sobre o uso de formulários no React. Na última vez, examinamos os recursos da interação de componentes e campos de texto. Aqui discutimos o trabalho com outros elementos do formulário.

→
Parte 1: visão geral do curso, razões para a popularidade do React, ReactDOM e JSX→
Parte 2: componentes funcionais→
Parte 3: arquivos de componentes, estrutura do projeto→
Parte 4: componentes pai e filho→
Parte 5: início do trabalho em um aplicativo TODO, noções básicas de estilo→
Parte 6: sobre alguns recursos do curso, JSX e JavaScript→
Parte 7: estilos embutidos→
Parte 8: trabalho contínuo na aplicação TODO, familiaridade com as propriedades dos componentes→
Parte 9: propriedades do componente→
Parte 10: Workshop sobre como trabalhar com propriedades e estilo de componentes→
Parte 11: geração dinâmica de marcação e método de matrizes de mapas→
Parte 12: workshop, terceira etapa do trabalho em uma aplicação TODO→
Parte 13: componentes baseados em classe→
Parte 14: workshop sobre componentes baseados em classe, status dos componentes→
Parte 15: oficinas de saúde componentes→
Parte 16: a quarta etapa do trabalho em um aplicativo TODO, manipulação de eventos→
Parte 17: quinta etapa do trabalho em um aplicativo TODO, modificando o estado dos componentes→
Parte 18: a sexta etapa do trabalho em um aplicativo TODO→
Parte 19: métodos do ciclo de vida dos componentesParte 20: a primeira lição sobre renderização condicional→
Parte 21: segunda lição e workshop sobre renderização condicional→
Parte 22: sétima etapa do trabalho em um aplicativo TODO, baixando dados de fontes externas→
Parte 23: primeira lição sobre como trabalhar com formulários→
Parte 24: Segunda lição sobre formulários→
Parte 25: Workshop sobre como trabalhar com formulários→
Parte 26: arquitetura do aplicativo, padrão Container / Component→
Parte 27: projeto do cursoLição 42. Trabalhando com Formulários, Parte 2
→
OriginalNesta lição, falaremos sobre campos para inserir texto de várias linhas, sobre sinalizadores, sobre botões de opção (eles também são chamados de "botões de opção") e sobre campos de lista. Até o momento, consideramos apenas trabalhar com campos de entrada de texto comuns.
Aqui está o código para o componente
App
o qual iniciaremos as experiências de hoje:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { firstName: "", lastName: "" } this.handleChange = this.handleChange.bind(this) } handleChange(event) { const {name, value} = event.target this.setState({ [name]: value }) } render() { return ( <form> <input type="text" value={this.state.firstName} name="firstName" placeholder="First Name" onChange={this.handleChange} /> <br /> <input type="text" value={this.state.lastName} name="lastName" placeholder="Last Name" onChange={this.handleChange} /> { /** * : * * <textarea /> * <input type="checkbox" /> * <input type="radio" /> * <select> <option> */ } <h1>{this.state.firstName} {this.state.lastName}</h1> </form> ) } } export default App
É assim que a página do aplicativo se parece no navegador nesta fase do trabalho.
Página do aplicativo no navegadorOs formulários geralmente contêm não apenas campos nos quais as linhas curtas são inseridas. Ao equipar formulários com outros elementos, trabalhar com eles no React é um pouco complicado, embora não haja nada de especial nisso.
No código acima, há um fragmento comentado que lista os elementos sobre os quais falaremos. Vamos começar com o campo para inserir texto com várias linhas - o elemento
textarea
. Provavelmente é mais fácil entender como trabalhar com ele. Se você costumava usar esse elemento ao criar formulários HTML regulares, sabe que essa não é uma tag de fechamento automático, como foi o caso do elemento de
input
. Possui peças de abertura e fechamento.
Adicione esse elemento ao formulário inserindo, imediatamente após o comentário, o seguinte código:
<br /> <textarea></textarea>
Se agora você olha para a página do aplicativo, pode ver como um campo para inserir texto de várias linhas apareceu nele.
Campo para inserir texto na páginaComo você pode ver, esse campo é um pouco mais alto que os campos comuns, o usuário pode alterar seu tamanho usando o marcador no canto inferior direito. Graças aos
cols
rows
e
rows
cols
você pode especificar suas dimensões ao descrever este elemento. Em HTML normal, se você quiser ter algum texto depois que o campo for exibido, isso será feito inserindo o texto desejado entre as tags de abertura e fechamento do elemento. No React, trabalhar com esses elementos é o mais semelhante possível ao trabalho com elementos de
input
, sobre os quais falamos da última vez. Ou seja, em React, a tag
textarea
é de fechamento automático. Ou seja, o código para exibir o campo na página pode ser alterado da seguinte maneira:
<textarea />
Você pode usar o atributo
value
nesta tag; além disso, o trabalho é realizado exatamente da mesma maneira que com o mesmo atributo dos campos de texto comuns. Devido a isso, é obtida uniformidade no trabalho com diferentes elementos e, além disso, é mais fácil atualizar o conteúdo dos campos, atualizando as propriedades do estado associadas a esses campos. Vamos trazer o estado do código do campo para este formulário:
<textarea value={"Some default value"}/>
Isso fará com que o texto especificado apareça no campo quando for exibido na página.
O texto que aparece no campoVoltaremos a trabalhar com o campo para inserir texto de várias linhas, mas, por enquanto, falaremos sobre sinalizadores. Uma caixa de seleção é um controle de
input
cujo tipo é a
checkbox
. Aqui está a descrição dele:
<input type="checkbox" />
Aqui está a aparência da bandeira descrita por essa marcação na página.
Caixa de seleçãoO principal recurso desse controle é o fato de o atributo
value
não ser usado ao trabalhar com ele. É usado para fornecer ao usuário uma escolha de duas opções, uma das quais corresponde à caixa de seleção e a outra à desmarcada. Para rastrear se a caixa de seleção está marcada ou desmarcada, o atributo
checked
é usado, descrito por um valor lógico. Como resultado, os sinalizadores geralmente correspondem às propriedades lógicas armazenadas no estado.
Vamos trazer o estado do componente para este formulário:
this.state = { firstName: "", lastName: "", isFriendly: true }
O código de descrição do sinalizador é alterado da seguinte maneira:
<input type="checkbox" checked={this.state.isFriendly} />
Depois disso, a caixa de seleção selecionada será exibida na página.
Caixa marcadaÉ verdade que agora ele não responde aos cliques nele. O fato é que o sinalizador está vinculado à variável correspondente armazenada no estado; portanto, quando tentamos removê-lo, React, verificando o estado e descobrindo que a propriedade
isFriendly
configurada como
true
, não permite isso. Ao mesmo tempo, um aviso será exibido no console, informando que não fornecemos um mecanismo para alterar o campo (
onChange
eventos
onChange
) e que ele foi exibido em um estado somente leitura.
Aviso do consolePodemos muito bem escrever um método especial para trabalhar com o sinalizador, mas o código do nosso componente já possui o método
handleChange()
. Agora é usado para trabalhar com campos de texto. Vamos pensar em como usá-lo para trabalhar com a bandeira. Para fazer isso, primeiro atribua o método acima como o
onChange
eventos
onChange
sinalizador e atribua ao sinalizador um nome correspondente ao nome da propriedade state relacionada ao sinalizador. Além disso, assinaremos a bandeira usando a tag
label
:
<label> <input type="checkbox" name="isFriendly" checked={this.state.isFriendly} onChange={this.handleChange} /> Is friendly? </label>
No método
handleChange()
, cujo código é mostrado abaixo, ao trabalhar com campos de texto, descobrimos o nome do elemento (
name
) e seu conteúdo (
value
), após o qual atualizamos o estado escrevendo nele o que o campo com um determinado nome em seu atributo
value
:
handleChange(event) { const {name, value} = event.target this.setState({ [name]: value }) }
Agora precisamos descobrir como lidar com uma bandeira que não tem atributo de
value
. Ele possui apenas o atributo
checked
, que pode aceitar apenas valores
true
ou
false
. Como resultado, para usar o método
handleChange()
para trabalhar com um sinalizador, precisamos verificar se o elemento para o qual esse manipulador é chamado é um sinalizador. Para executar essa verificação, lembramos que o tipo (
type
) do elemento de
input
que representa o sinalizador está definido como
checkbox
de
checkbox
. Para verificar esse valor, você pode consultar a propriedade
type
do elemento
event.target
.
event.target
essa propriedade de
event.target
, bem como a propriedade
checked
, usando a seguinte construção:
const {name, value, type, checked} = event.target
Agora podemos verificar o valor da constante de
type
e descobrir se o elemento para o qual o manipulador de eventos é chamado é um sinalizador. Se for esse o caso, escreveremos no estado o que acabou por estar na constante
checked
. Não esqueça de salvar o código responsável por trabalhar com campos de texto. Como resultado, o código
handleChange()
assume o seguinte formato:
handleChange(event) { const {name, value, type, checked} = event.target type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value }) }
Depois disso, verifique o funcionamento da bandeira.
Verificando o funcionamento da bandeiraComo você pode ver, agora ele pode ser removido e instalado. Ao mesmo tempo, o trabalho dos campos de texto não está quebrado. Uma notificação referente à caixa de seleção desapareceu do console, mas é exibida uma notificação referente ao campo para inserir texto de várias linhas. Altere o código que descreve esse campo da seguinte maneira:
<textarea value={"Some default value"} onChange={this.handleChange} />
Isso levará ao desaparecimento da notificação, embora não tenhamos implementado outros mecanismos para trabalhar com esse campo usando as ferramentas do componente (não especificamos um nome para o campo, não adicionamos a propriedade correspondente ao estado). Você pode implementar esses recursos você mesmo. Agora vamos falar sobre switches.
Eles podem ser representados como uma combinação de elementos de
input
dos tipos de
text
e
checkbox
. O que se entende aqui é que os comutadores têm um atributo
value
e um atributo
checked
. Adicione algumas opções ao nosso formulário, criando seu código com base no código de descrição do sinalizador. Aqui está o que parece:
<label> <input type="radio" name="gender" value="male" checked={this.state.isFriendly} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.isFriendly} onChange={this.handleChange} /> Female </label>
Criamos esse código com base no código de descrição da bandeira e ainda não editamos nada. Portanto, os comutadores se comportam de maneira estranha. Em particular, se a caixa de seleção estiver desmarcada, os dois comutadores estão no estado "desligado" e, se você selecionar a caixa de seleção, um deles ficará "ativado". Esses erros podem ser evitados tratando cuidadosamente o código do elemento se ele for criado com base no código dos elementos existentes. Agora vamos consertar isso.
Observe que esses dois elementos têm o mesmo nome -
gender
. Switches com o mesmo nome formam um grupo. Somente uma opção incluída nesse grupo pode ser selecionada.
Ao configurar os comutadores, você não pode simplesmente indicar que o valor
checked
está definido, digamos, para
true
se alguma propriedade de estado for
true
. Os switches devem suportar alterações sincronizadas, dentro do grupo, em seu próprio estado. Em vez disso, o valor
checked
dos comutadores é definido por condição. No nosso caso, essa condição será representada pela comparação da propriedade do estado
this.state.gender
com a cadeia
male
ou
female
. No código de descrição do comutador, fica assim:
<label> <input type="radio" name="gender" value="male" checked={this.state.gender === "male"} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.gender === "female"} onChange={this.handleChange} /> Female </label>
Agora adicione uma nova propriedade,
gender
, ao estado, inicializando-a com uma string vazia:
this.state = { firstName: "", lastName: "", isFriendly: false, gender: "" }
Depois disso, os comutadores funcionarão independentemente da caixa de seleção. Adicione à saída de código do componente um cabeçalho de segundo nível que exibe informações sobre qual opção está selecionada:
<h2><font color="#3AC1EF">You are a {this.state.gender}</font></h2>
Aqui, provavelmente, vale a pena introduzir algum mecanismo de renderização condicional. Isso permitirá que, ao abrir a página, quando nenhum dos botões de opção esteja selecionado, verifique se o texto
You are a
não seria exibido nela, mas não faremos isso, embora você possa implementá-lo. Agora vamos dar uma olhada no que conseguimos.
Alterna na página do aplicativoTudo o que falamos aqui pode parecer bastante complicado. Em particular, isso diz respeito à memorização dos recursos de diferentes controles. Para simplificar o trabalho com formulários, você pode usar bibliotecas especializadas. Por exemplo, a biblioteca
formik . Essa biblioteca simplifica bastante o processo de desenvolvimento de formulários nos aplicativos React.
Agora vamos falar sobre os campos da lista.
No HTML normal, as seguintes construções são usadas para descrever caixas de combinação:
<select> <option></option> <option></option> <option></option> <select/>
O React adota uma abordagem semelhante, embora, como em outros elementos, o atributo
value
seja usado. Isso facilita descobrir exatamente qual item da lista está selecionado e, além disso, facilita o trabalho com o estado do componente.
Suponha que desejemos criar uma caixa de combinação que permita ao usuário selecionar sua cor favorita. Para fazer isso, você pode colocar a seguinte construção no atributo
value
do elemento
select
:
value={this.state.favColor}
. Isso obterá os valores que o usuário seleciona. Agora adicione
favColor
ao estado:
this.state = { firstName: "", lastName: "", isFriendly: false, gender: "", favColor: "blue" }
Em seguida, equipamos a caixa de combinação com o
onChange
eventos
onChange
e
onChange
um nome a ela. Também atribuímos valores aos elementos de
options
da caixa de combinação e inserimos o texto que será exibido na caixa.
Aqui está a aparência de um elemento de
select
assinatura
select
com uma assinatura:
<label>Favorite Color:</label> <select value={this.state.favColor} onChange={this.handleChange} name="favColor" > <option value="blue">Blue</option> <option value="green">Green</option> <option value="red">Red</option> <option value="orange">Orange</option> <option value="yellow">Yellow</option> </select>
Agora adicione outra inscrição ao formulário que exibe a cor favorita do usuário:
<h2><font color="#3AC1EF">Your favorite color is {this.state.favColor}</font></h2>
É hora de experimentar a caixa de combinação.
Caixa de combinaçãoComo você pode ver, embora nossa forma não brilha com a sofisticação do design, os controles colocados nela funcionam como esperado.
Graças à maneira como os controles React são organizados no React, é fácil usar o mesmo manipulador para lidar com os eventos deles. Este é exatamente o esquema de trabalho usado no nosso caso. O único recurso do nosso manipulador
handleChange()
é que precisamos manipular eventos de flag de uma maneira especial.
Agora, vamos falar sobre o envio do formulário ou o processamento dos valores inseridos nele após a conclusão de seu preenchimento. Existem duas abordagens para executar essas ações. Ao usar qualquer um deles, o formulário deve estar equipado com um botão:
<button>Submit</button>
No HTML5, se um elemento do
button
for encontrado no formulário, ele funcionará como um elemento de
input
antigo do tipo
submit
. Se você clicar nesse botão, um evento do próprio formulário
onSubmit
será acionado. Se você precisar fazer algo depois de preencher o formulário, poderá adicionar o
onClick
eventos
onClick
ao botão, mas, por exemplo, eu pessoalmente prefiro manipular esses eventos no nível do formulário, atribuindo o manipulador de eventos
onSubmit
a
onSubmit
:
<form onSubmit={this.handleSubmit}>
O método usado como manipulador para este evento ainda não foi gravado. Este é um manipulador de eventos regular, que, por exemplo, referindo-se a uma determinada API, passa dados de formulário para ele.
Sumário
Nesta lição, concluímos nossa conversa sobre como trabalhar com formulários no React. Da próxima vez, você encontrará trabalhos práticos sobre esse tópico.
Caros leitores! Se você tentou usar a biblioteca formik para criar formulários no React, informe-nos.
