Tutorial Reagir Parte 18: A sexta fase do trabalho em um aplicativo TODO

Na parte atual da tradução do curso de treinamento do React, você está convidado a continuar trabalhando no aplicativo Todo e certifique-se de que clicar nos sinalizadores afete o estado do componente.

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 33. Oficina. Aplicação TODO. Estágio número 6


Original

▍Job


Nesta lição prática, continuaremos a trabalhar no aplicativo Todo e garantiremos que as ações do usuário afetem o estado do componente. Trata-se de tornar possível marcar os itens da lista de tarefas como concluídos ou não concluídos. Abaixo está o código do componente App , algumas das peças de trabalho e comentários disponíveis projetados para ajudá-lo a concluir a tarefa. De fato, eis o que você está convidado a fazer hoje:

  1. Crie um manipulador de eventos no componente App que responda às alterações do sinalizador (estamos falando do evento onChange ) e altere o estado do aplicativo de acordo. Talvez essa seja a parte mais difícil da tarefa de hoje. Para lidar com isso - preste atenção aos comentários e espaços em branco fornecidos no código.
  2. Passe o método apropriado para o componente TodoItem .
  3. No componente TodoItem crie um mecanismo que, quando o evento onChange , chame o método passado para a instância do componente e o identificador de caso ( id ), que corresponde ao sinalizador no qual o usuário clicou.

Aqui está o código para o componente App :

 import React from "react" import TodoItem from "./TodoItem" import todosData from "./todosData" class App extends React.Component {   constructor() {       super()       this.state = {           todos: todosData       }       this.handleChange = this.handleChange.bind(this)   }     handleChange(id) {       //   ,      id        // completed   c false  true ( ).       //   ,       .       //       ,  .       // (  ,       map.)   }     render() {       const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item}/>)             return (           <div className="todo-list">               {todoItems}           </div>       )   } } export default App 

▍Solução


Para começar, crie um mecanismo simples para verificar a chamada para o método handleChange() . Ou seja, trazemos para este formulário:

 handleChange(id) {   console.log("Changed", id) } 

Agora, estamos implementando o que precisa ser feito de acordo com os parágrafos 2 e 3 da tarefa. Ou seja, criaremos uma conexão entre clicar no sinalizador e chamar o método handleChange() passando o id desse sinalizador para ele.

Para passar uma referência para handleChange() para uma instância do componente TodoItem , podemos fazer o mesmo que passar propriedades para ele e reescrever o código para criar a lista de componentes como esta:

 const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange}/>) 

Observe que a propriedade handleChange , que estará disponível para os componentes TodoItem , contém uma referência ao método handleChange da instância do componente App . No componente TodoItem , esse método pode ser acessado da mesma maneira que outras propriedades passadas para ele. Nesta fase, o código TodoItem parece com o seguinte:

 import React from "react" function TodoItem(props) {   return (       <div className="todo-item">           <input               type="checkbox"               checked={props.item.completed}               onChange={() => console.log("Changed!")}           />           <p>{props.item.text}</p>       </div>   ) } export default TodoItem 

Para chamar o método handleChange no código do componente, você pode usar uma construção do formulário props.handleChange() . Nesse caso, esse método precisa passar o id elemento. O onChange eventos onChange aceita um objeto de evento. Não precisamos desse objeto para chamar o método handleChange() . Reescrevemos o código no qual atribuímos o manipulador de eventos onChange ao elemento, da seguinte maneira:

 onChange={(event) => props.handleChange(props.item.id)} 

Aqui chamamos o método handleChange() , passando para ele o identificador de elemento obtido das propriedades passadas para ele, de outra função que aceita o objeto de evento. Como não estamos usando esse objeto aqui, o código pode ser reescrito assim:

 onChange={() => props.handleChange(props.item.id)} 

Agora tente executar o aplicativo e, abrindo o console, clique nas caixas de seleção.


Testando o método handleChange ()

As mensagens que contêm identificadores de sinalizadores pelas quais clicamos chegam ao console. Mas os sinalizadores ainda não alteram a aparência, pois o método handleChange() não implementou um mecanismo para alterar o estado de um componente. Como resultado, acabamos de lidar com a segunda e a terceira parte da tarefa e agora podemos começar a trabalhar em sua primeira parte, talvez a mais interessante de todas, em relação ao trabalho com o Estado.

Para começar, precisamos resolver o problema referente ao estado em que uma matriz está armazenada em um estado, cujo elemento, em resposta a um clique em um sinalizador, deve sofrer alterações, mas não devemos modificar a matriz armazenada na versão antiga do estado. Ou seja, por exemplo, você não pode simplesmente percorrer uma variedade de objetos que já estão em um estado, encontrar o elemento necessário e alterar sua propriedade completed . Precisamos que, depois de alterar o estado, uma nova matriz seja formada, um dos elementos será alterado e o restante permanecerá o mesmo de antes. Uma das abordagens para a formação dessa matriz é o uso do método da matriz map() , mencionado nos comentários da tarefa. Vamos escrever o código no método setState() . Vamos handleChange() código do método handleChange() do componente App para o seguinte formato:

 handleChange(id) {   this.setState(prevState => {         }) } 

Agora, usando o método map() , percorreremos a matriz prevState.todos e procuraremos o elemento que precisamos nela, ou seja, aquele cujo id é passado para o método handleChange() e, em seguida, alteraremos sua propriedade completed . O método map() retorna uma nova matriz, que será usada no novo estado do aplicativo, portanto, gravaremos essa matriz em uma constante. Aqui está o que parece:

 handleChange(id) {   this.setState(prevState => {       const updatedTodos = prevState.todos.map(todo => {           if (todo.id === id) {               todo.completed = !todo.completed           }           return todo       })       return {           todos: updatedTodos       }   }) } 

Aqui, durante o processamento da matriz usando map() , se um elemento cujo id é igual ao id passado para o método handleChange() for handleChange() , o valor da propriedade completed desse elemento será revertido ( true para false e vice-versa). Depois disso, independentemente de o elemento ter sido alterado, map() retorna esse elemento. Ele cai em uma nova matriz (representada pela constante updatedTodos ) no mesmo índice sob o qual o elemento correspondente estava na matriz todos da versão anterior do estado. Depois que toda a matriz é varrida e a matriz updatedTodos é totalmente formada, essa matriz é usada como o valor da propriedade todos do objeto retornado pelo método setState() , que é uma nova versão do estado.

Se você iniciar o aplicativo agora, poderá descobrir que os sinalizadores respondem aos nossos efeitos. Isso sugere que clicar neles altera o estado do aplicativo, após o qual eles são renderizados novamente usando novos dados.

Sumário


Hoje, tínhamos à nossa disposição um aplicativo Todo em funcionamento, quando escrevemos, usando muitos dos conceitos de React que estudamos. De fato, ainda é possível refiná-lo, em particular, estilizá-lo e expandir suas capacidades. Voltaremos a ele em uma das seguintes aulas.

Caros leitores! Você lidou com o trabalho prático de hoje?

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


All Articles