Tutorial React Parte 18: La sexta fase de trabajar en una aplicación TODO

En la parte de hoy de la traducción del tutorial React, está invitado a seguir trabajando en la aplicación Todo y asegurarse de que al hacer clic en las banderas afecta el estado del componente.

imagen

Parte 1: descripción general del curso, razones de la popularidad de React, ReactDOM y JSX
Parte 2: componentes funcionales
Parte 3: archivos de componentes, estructura del proyecto
Parte 4: componentes principales y secundarios
Parte 5: inicio del trabajo en una aplicación TODO, los fundamentos del estilo
Parte 6: sobre algunas características del curso, JSX y JavaScript
Parte 7: estilos en línea
Parte 8: trabajo continuo en la aplicación TODO, familiaridad con las propiedades de los componentes
Parte 9: propiedades del componente
Parte 10: Taller sobre trabajo con propiedades de componentes y estilo
Parte 11: generación de marcado dinámico y método de matrices de mapas
Parte 12: taller, tercera etapa de trabajo en una aplicación TODO
Parte 13: componentes basados ​​en clases
Parte 14: taller sobre componentes basados ​​en la clase, estado de los componentes.
Parte 15: talleres de componentes de salud
Parte 16: la cuarta etapa de trabajo en una aplicación TODO, manejo de eventos
Parte 17: quinta etapa de trabajo en una aplicación TODO, modificando el estado de los componentes
Parte 18: la sexta etapa de trabajo en una aplicación TODO
Parte 19: métodos del ciclo de vida de los componentes.
Parte 20: la primera lección de representación condicional
Parte 21: segunda lección y taller sobre representación condicional
Parte 22: la séptima etapa de trabajo en una aplicación TODO, descargando datos de fuentes externas
Parte 23: primera lección sobre trabajar con formularios
Parte 24: Segunda lección de formularios
Parte 25: Taller sobre trabajo con formularios
Parte 26: arquitectura de la aplicación, patrón de contenedor / componente
Parte 27: proyecto del curso

Lección 33. Taller. TODO aplicación. Etapa número 6


Original

▍Trabajo


En esta lección práctica, continuaremos trabajando en la aplicación Todo y nos aseguraremos de que las acciones del usuario afecten el estado del componente. Se trata de hacer posible que marquemos los elementos de la lista de tareas pendientes como completados o no completados. A continuación se muestra el código del componente de la App , algunas de las piezas de trabajo y comentarios disponibles en los que están diseñados para ayudarlo a completar la tarea. De hecho, esto es lo que está invitado a hacer hoy:

  1. Cree un controlador de eventos en el componente de la App que responda a los cambios de onChange (estamos hablando del evento onChange ) y cambia el estado de la aplicación en consecuencia. Quizás esta sea la parte más difícil de la tarea de hoy. Para enfrentarlo, preste atención a los comentarios y espacios en blanco provistos en el código.
  2. Pase el método apropiado al componente TodoItem .
  3. En el componente TodoItem cree un mecanismo que, cuando onChange evento onChange , llame al método pasado a la instancia del componente y le pase el identificador de caso ( id ), que corresponde al indicador en el que hizo clic el usuario.

Aquí está el código para el componente de la 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 

▍Solución


Para comenzar, cree un mecanismo simple para verificar la llamada al método handleChange() . A saber, lo traemos a esta forma:

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

Ahora estamos implementando lo que se debe hacer de acuerdo con los párrafos 2 y 3 de la tarea. Es decir, crearemos una conexión entre hacer clic en la bandera y llamar al método handleChange() con pasarle la id esta bandera.

Para pasar una referencia a handleChange() a una instancia del componente TodoItem , podemos hacer lo mismo que pasarle propiedades y reescribir el código para crear la lista de componentes de esta manera:

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

Tenga en cuenta que la propiedad handleChange , que estará disponible para los componentes TodoItem , contiene una referencia al método handleChange de la instancia del componente App . En el componente TodoItem , se puede acceder a este método de la misma manera que otras propiedades que se le pasan. En esta etapa, el código de TodoItem ve así:

 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 llamar al método handleChange en el código del componente, puede usar una construcción del formulario props.handleChange() . En este caso, este método necesita pasar la id elemento. El onChange eventos onChange acepta un objeto de evento. No necesitamos este objeto para llamar al método handleChange() . Reescribimos el código en el que asignamos el controlador de eventos onChange al elemento, de la siguiente manera:

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

Aquí llamamos al método handleChange() , pasándole el identificador de elemento tomado de las propiedades que le pasaron, de otra función que acepta el objeto de evento. Como no estamos usando este objeto aquí, el código se puede reescribir así:

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

Ahora intente ejecutar la aplicación y, abriendo la consola, haga clic en las casillas de verificación.


Probar el método handleChange ()

Los mensajes que contienen identificadores de banderas por los que hacemos clic llegan a la consola. Pero las banderas aún no cambian la apariencia, ya que el método handleChange() no ha implementado un mecanismo para cambiar el estado de un componente. Como resultado, acabamos de hacer frente a la segunda y tercera parte de la tarea y ahora podemos comenzar a trabajar en su primera parte, quizás la más interesante de todas, con respecto al trabajo con el estado.

Para comenzar, debemos resolver el problema con respecto al estado en que una matriz se almacena en un estado, cuyo elemento, en respuesta a un clic en un indicador, debe sufrir cambios, pero no debemos modificar la matriz almacenada en la versión anterior del estado. Es decir, por ejemplo, no puede simplemente recorrer una matriz de objetos que ya están en un estado, encontrar el elemento necesario y cambiar su propiedad completed . Necesitamos que, después de cambiar el estado, se forme una nueva matriz, uno de los elementos de los cuales se cambiará, y el resto seguirá siendo el mismo que antes. Uno de los enfoques para la formación de dicha matriz es el uso del método de matriz map() , mencionado en los comentarios a la tarea. Escribiremos el código en el método setState() . Llevemos handleChange() código del método handleChange() del componente de la App al siguiente formulario:

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

Ahora, usando el método map() , prevState.todos matriz prevState.todos y buscaremos el elemento que necesitamos en él, es decir, aquel cuya id se pasa al método handleChange() , y luego cambiaremos su propiedad completed . El método map() devuelve una nueva matriz, que se utilizará en el nuevo estado de la aplicación, por lo que escribiremos esta matriz en una constante. Así es como se ve:

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

Aquí, durante el procesamiento de la matriz usando map() , si se handleChange() un elemento cuyo id es igual al id pasado al método handleChange() , el valor de la propiedad completed de este elemento se invierte ( true a false y viceversa). Después de eso, independientemente de si el elemento ha cambiado, map() devuelve ese elemento. Cae en una nueva matriz (representada por la constante updatedTodos ) bajo el mismo índice bajo el cual el elemento correspondiente estaba en la matriz todos de la versión anterior del estado. Después de escanear toda la matriz y de que la matriz updatedTodos esté completamente formada, esta matriz se usa como el valor de la propiedad todos del objeto devuelto por el método setState() , que es una nueva versión del estado.

Si inicia la aplicación ahora, es posible que las banderas respondan a nuestros efectos. Esto sugiere que al hacer clic en ellos cambia el estado de la aplicación, después de lo cual se vuelven a representar con nuevos datos.

Resumen


Hoy, teníamos a nuestra disposición una aplicación Todo que funcionaba, al escribir, en la que utilizamos muchos de los conceptos de React que estudiamos. De hecho, todavía es bastante posible refinarlo, en particular, estilizarlo y ampliar sus capacidades. Volveremos a él en una de las siguientes clases.

Estimados lectores! ¿Te enfrentaste al trabajo práctico de hoy?

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


All Articles