Nesta parte da tradução do tutorial React, falaremos sobre como trabalhar com formulários. Em particular, a lição de hoje é dedicada à organização da interação de componentes e campos de texto.

→
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 41. Trabalhando com Formulários, Parte 1
→
OriginalOs formulários são uma parte importante dos aplicativos da web. Mas, como se viu, os envolvidos no desenvolvimento do React, trabalhando com formas, geralmente causam certas dificuldades. O fato é que o React trabalha com formulários de uma maneira especial. Nesta lição, usaremos o projeto padrão criado por create-
App.js
-app, cujo formato inicial do arquivo
App.js
é apresentado abaixo.
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } render() { return ( <div> Code goes here </div> ) } } export default App
Observe que, para dominar o material desta lição, você deve estar familiarizado com o conceito do estado do aplicativo. Se você trabalhou em todas as lições anteriores do curso e em oficinas concluídas independentemente, isso significa que você tem o conhecimento necessário aqui.
Aqui está a documentação do React nos formulários. É recomendável que você olhe para ela antes de continuar.
Portanto, no React, os formulários funcionam de maneira um pouco diferente do que o JavaScript comum. Nomeadamente, na abordagem usual, os formulários são descritos usando HTML nas páginas da Web, após o que, usando a API DOM, eles interagem com eles a partir do JavaScript. Em particular, clicando no botão enviar, eles coletam dados dos campos preenchidos pelo usuário e os preparam para o envio ao servidor, verificando-os e, se necessário, informando ao usuário que ele preencheu alguns campos incorretamente. No React, em vez de esperar que todos os materiais sejam inseridos nos campos do formulário antes de prosseguir com o processamento do software, os dados são monitorados constantemente usando o estado do aplicativo. Isso, por exemplo, se resume ao fato de que cada caractere digitado pelo usuário pelo teclado entra imediatamente no estado. Como resultado, no aplicativo React, podemos trabalhar rapidamente com a versão mais recente do que o usuário digita nos campos do formulário. Para demonstrar essa idéia em ação, começamos com uma descrição do formulário que contém um campo de texto regular.
Para fazer isso, no código que o método
render()
retorna, descrevemos o formulário. Na abordagem usual, esse formulário teria um botão, clicando no botão em que os mecanismos do programa do aplicativo começam a processar os dados inseridos nesse formulário. No nosso caso, os dados inseridos pelo usuário no campo irão para o aplicativo à medida que forem inseridos. Para fazer isso, precisamos manipular o
onChange
campo
onChange
. No manipulador deste evento (vamos chamá-lo de
handleChange()
), atualizaremos o estado escrevendo nele o que é inserido no campo. Para fazer isso, precisamos primeiro descobrir o que está contido no campo e, em segundo lugar, colocar esses dados em um estado. No estado, crie uma propriedade que armazene o conteúdo do campo. Vamos usar esse campo para armazenar o primeiro nome do usuário, portanto, chamaremos a propriedade correspondente
firstName
e a inicializaremos com uma string vazia.
Depois disso, no construtor,
handleChange()
o manipulador de eventos
handleChange()
a
this
e no código do manipulador usaremos a função
setState()
. Como o valor anterior que foi armazenado na propriedade de estado
firstName
não é do nosso interesse, podemos simplesmente passar um objeto com o novo valor
firstName
para essa função. O que deve ser escrito nessa propriedade?
Se você se lembrar de como os manipuladores de eventos funcionam em JavaScript, acontece que, quando chamados, recebem alguns parâmetros predefinidos. No nosso caso, o objeto de evento é passado para o manipulador. Ele contém os dados que nos interessam. O campo de texto cujo evento
onChange
que estamos processando é representado neste objeto como
event.target
. E o conteúdo desse campo pode ser acessado usando a construção
event.target.value
.
Agora, no método
render()
, produziremos o que será armazenado no estado e veremos o que obtivemos.
Aqui está o código que implementa as idéias acima.
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { firstName: "" } this.handleChange = this.handleChange.bind(this) } handleChange(event) { this.setState({ firstName: event.target.value }) } render() { return ( <form> <input type="text" placeholder="First Name" onChange={this.handleChange} /> <h1>{this.state.firstName}</h1> </form> ) } } export default App
É assim que tudo parece no navegador.
Página do aplicativo no navegadorCada caractere inserido no campo aparece imediatamente no elemento
<h1>
presente na página.
Agora vamos pensar em como adicionar outro campo ao formulário, para o sobrenome do usuário. Obviamente, para estabelecer o processamento correto dos dados inseridos nesse campo, precisaremos adicionar outra propriedade ao estado e trabalhar em mecanismos que atualizem o estado ao inserir dados no campo.
Uma abordagem para resolver esse problema é criar um manipulador de eventos separado para o novo campo. Para um formulário pequeno com vários campos de entrada, essa é uma abordagem completamente normal, mas se estamos falando de um formulário com dezenas de campos, criar um manipulador de eventos
onChange
separado para cada um deles não é uma boa idéia.
Para distinguir os campos no mesmo manipulador de eventos quando ele é alterado, atribuiremos as propriedades do
name
aos campos, que faremos exatamente o mesmo que os nomes das propriedades usadas para armazenar os dados do campo no estado (
firstName
e
lastName
). Depois disso, podemos, trabalhando com o objeto de evento que é passado para o manipulador, descobrir o nome do campo, as alterações que levaram à sua invocação e usar esse nome. Nós o usaremos definindo o nome da propriedade state na qual queremos adicionar dados atualizados. Aqui está o código que implementa esse recurso:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { firstName: "", lastName: "" } this.handleChange = this.handleChange.bind(this) } handleChange(event) { this.setState({ [event.target.name]: event.target.value }) } render() { return ( <form> <input type="text" name="firstName" placeholder="First Name" onChange={this.handleChange} /> <br /> <input type="text" name="lastName" placeholder="Last Name" onChange={this.handleChange} /> <h1>{this.state.firstName} {this.state.lastName}</h1> </form> ) } } export default App
Observe que, definindo o nome da propriedade do objeto passado para
setState()
, colocamos
setState()
construção
event.target.name
entre colchetes retangulares.
Página do aplicativo no navegadorA página agora exibe o que é inserido no primeiro campo e o que é inserido no segundo campo.
Os princípios de trabalho com campos de texto que acabamos de examinar também são válidos para outros campos baseados neles. Por exemplo, esses podem ser campos para inserir endereços de email, telefones e números. Os dados inseridos nesses campos podem ser processados usando os mecanismos discutidos acima, para a operação da qual é importante que os nomes dos campos correspondam aos nomes das propriedades no estado do componente que armazena os dados desses campos.
Falaremos sobre como trabalhar com outros elementos de formulário na próxima lição. Aqui, abordaremos outro tópico relacionado ao chamado "componente controlado", sobre o qual você, se consultou a
documentação do React em formulários, já leu algo.
Se desejarmos que o que é exibido no campo corresponda exatamente ao que está armazenado no estado do aplicativo, podemos usar a abordagem descrita acima, na qual o estado é atualizado à medida que você insere dados no campo. A condição é reativa. E ao usar elementos de formulário que são componentes gerenciados, o que é exibido nesses elementos é controlado pelo estado. É com essa abordagem que é a única fonte de dados de componentes verdadeiros. Para conseguir isso, basta adicionar o atributo
value
ao código que descreve o elemento do formulário, indicando a propriedade state correspondente ao campo. Aqui está a aparência do código do aplicativo.
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { firstName: "", lastName: "" } this.handleChange = this.handleChange.bind(this) } handleChange(event) { this.setState({ [event.target.name]: event.target.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} /> <h1>{this.state.firstName} {this.state.lastName}</h1> </form> ) } } export default App
Após essas alterações, o aplicativo funciona exatamente como antes. A principal diferença de sua versão anterior é que o campo exibe o que está armazenado no estado.
Quero dar um conselho que salvará você no futuro de erros que são muito difíceis de depurar. Aqui está a aparência do código do manipulador de eventos
onChange
agora:
handleChange(event) { this.setState({ [event.target.name]: event.target.value }) }
É recomendável que, em vez de acessar diretamente as propriedades do objeto de
event
ao construir o objeto passado para
setState()
, extraia antecipadamente o que você precisa:
handleChange(event) { const {name, value} = event.target this.setState({ [name]: value }) }
Aqui não entraremos em detalhes sobre erros que podem ser evitados através da construção de manipuladores de eventos dessa maneira. Se você estiver interessado, consulte o
SyntheticEvent na documentação do React.
Sumário
Nesta lição, você se familiarizou com os mecanismos para trabalhar com formulários no React. Da próxima vez, continuaremos este tópico.
Caros leitores! Você usa bibliotecas adicionais ao trabalhar com formulários no React?