Tutorial Reagir Parte 24: Segunda lição sobre formulários

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.

imagem

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 componentes
Parte 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 curso

Lição 42. Trabalhando com Formulários, Parte 2


Original

Nesta 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 navegador

Os 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ágina

Como 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 campo

Voltaremos 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ção

O 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 console

Podemos 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 bandeira

Como 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 aplicativo

Tudo 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ção

Como 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.

Source: https://habr.com/ru/post/pt444356/


All Articles