Tutorial de React, Parte 17: La quinta etapa de trabajar en una aplicaci贸n TODO, modificar el estado de los componentes

En la parte de hoy de la traducci贸n del curso React, le sugerimos que complete la pr贸xima tarea pr谩ctica y presente a su atenci贸n una historia sobre c贸mo modificar el estado de los componentes React.

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 鈥嬧媏n clases
Parte 14: taller sobre componentes basados 鈥嬧媏n 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 31. Taller. TODO aplicaci贸n. Etapa n煤mero 5


Original

鈻峊rabajo


Al iniciar nuestra aplicaci贸n Todo, puede notar que se muestra una notificaci贸n en la consola que indica que nosotros, despu茅s de haber configurado la propiedad checked de un elemento en el componente TodoItem , no proporcionamos un mecanismo para interactuar con este elemento en forma de un onChange eventos onChange . Al trabajar con la interfaz de la aplicaci贸n, esto da como resultado el hecho de que los indicadores que se muestran en la p谩gina no se pueden marcar ni desmarcar.

Aqu铆 est谩 invitado a equipar un elemento del tipo de checkbox de checkbox del componente TodoItem con un controlador de eventos TodoItem , que, en esta etapa del trabajo, es suficiente presentarlo como una funci贸n que genera algo en la consola.

鈻峉oluci贸n


TodoItem es como se ve el c贸digo del componente TodoItem ahora, que se almacena en el archivo TodoItem.js :

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

Esto es lo que muestra la consola cuando se inicia la aplicaci贸n.


Notificaci贸n de consola

Al mismo tiempo, las banderas no responden a nuestros efectos.

Para deshacerse de esta notificaci贸n y preparar el proyecto para futuros trabajos, es suficiente asignar un onChange eventos onChange al elemento de checkbox . As铆 es como se ve en el c贸digo:

 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 

隆Aqu铆, como manejador, usamos una funci贸n simple que genera la palabra Checked! en la consola Checked! . Al mismo tiempo, al hacer clic en las banderas no se produce un cambio en su estado, pero la notificaci贸n de la consola, como se puede ver en la siguiente figura, desaparece.


Las banderas a煤n no funcionan, pero las notificaciones de la consola desaparecieron

Este peque帽o cambio realizado en la aplicaci贸n nos permitir谩, despu茅s de tratar el cambio en el estado de los componentes, hacer que las casillas de verificaci贸n funcionen correctamente.

Lecci贸n 32. Cambio del estado de los componentes


Original

Comencemos con una aplicaci贸n est谩ndar creada usando create-react-app , en el archivo App.js que contiene el siguiente c贸digo:

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }   }     render() {       return (           <div>               <h1>{this.state.count}</h1>               <button>Change!</button>           </div>       )   } } export default App 

El index.css estilos index.css , que se index.js en el archivo index.js , contiene la siguiente descripci贸n de estilos:

 div {   display: flex;   flex-direction: column;   align-items: center;   justify-content: center; } h1 {   font-size: 3em; } button {   border: 1px solid lightgray;   background-color: transparent;   padding: 10px;   border-radius: 4px;  } button:hover {   cursor: pointer; } button:focus {   outline:0; } 

En esta etapa, la aplicaci贸n se parece a la que se muestra en la siguiente figura.


P谩gina de aplicaci贸n en el navegador

Hoy hablaremos sobre c贸mo cambiar el estado de los componentes. Si el componente tiene un estado, esto permite, inicializ谩ndolo, almacenar algunos datos en 茅l. Pero si no se pudiera cambiar el estado, entonces el componente no se beneficiar铆a mucho de su presencia, almacenar los datos en 茅l no ser铆a muy diferente de, por ejemplo, copiarlos en el c贸digo del componente.

Hablemos de la aplicaci贸n, en cuyo ejemplo consideraremos trabajar con el estado del componente. El componente de la App cuyo c贸digo se presenta arriba es un componente basado en clases. Esto es bastante obvio, ya que necesitamos que este componente tenga un estado. En el c贸digo del componente, usamos el constructor.

En 茅l, como siempre, llamamos al m茅todo super() e inicializamos el estado escribiendo la propiedad de count y asign谩ndole un valor inicial de 0 . En el m茅todo render() , imprimimos un encabezado de primer nivel que representa el valor de la propiedad count del estado del componente, as铆 como un bot贸n con la palabra Change! . Todo esto est谩 formateado con estilos.

Si, en esta etapa del trabajo en la aplicaci贸n, 谩brala en un navegador y haga clic en el bot贸n, entonces, por supuesto, no pasar谩 nada. Pero debemos hacer clic en el bot贸n para cambiar el estado del componente, lo que afecta su propiedad de count . Al mismo tiempo, ya hemos estudiado la metodolog铆a para manejar eventos en React, y nuestra tarea es crear un mecanismo que, respondiendo a un clic en un bot贸n, cambie la propiedad de estado del count .

Comencemos a resolver nuestra tarea equipando el bot贸n con un onClick eventos onClick , que, para empezar, simplemente generar谩 algo en la consola.

Para hacer esto, agregaremos un nuevo m茅todo a la clase de componente. Puede llamarlo como desee, pero es habitual llamar a tales m茅todos para que sus nombres indiquen los eventos que est谩n procesando. Como resultado, nosotros, ya que lo vamos a usar para procesar el evento click , lo llamamos handleClick() . As铆 es como se ver谩 el c贸digo del componente de la App .

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }   }     handleClick() {       console.log("I'm working!")   }     render() {       return (           <div>               <h1>{this.state.count}</h1>               <button onClick={this.handleClick}>Change!</button>           </div>       )   } } export default App 

Tenga en cuenta que haciendo referencia a este m茅todo desde render() , utilizamos una construcci贸n del formulario this.handleClick .

Ahora, si hace clic en el bot贸n, el mensaje correspondiente aparecer谩 en la consola.


Al hacer clic en el bot贸n se llama al m茅todo de clase.

Ahora hagamos que al hacer clic en el bot贸n aumente el n煤mero que se muestra arriba, es decir, modificar el estado del componente. 驴Quiz谩s intente cambiar el estado del componente directamente, en el m茅todo handleClick() ? Digamos que si reescribimos este m茅todo as铆:

 handleClick() {   this.state.count++ } 

Debo decir de inmediato que esto no funciona con el estado de los componentes en React. Intentar ejecutar dicho c贸digo arrojar谩 un error.

La condici贸n del componente se puede comparar con la ropa que usa una persona. Si quiere cambiarse de ropa, entonces no se cambia ni repinta la ropa sin quitarse la ropa, sino que se la quita y se pone algo m谩s. De hecho, as铆 es exactamente c贸mo funcionan con el estado de los componentes.

Puede recordar que hablamos sobre un m茅todo especial utilizado para modificar el estado, disponible en componentes basados 鈥嬧媏n clases debido al hecho de que extienden la clase React.Component . Este es el m茅todo setState() . Se utiliza en casos en los que necesita cambiar el estado de un componente. Este m茅todo puede usarse de diferentes maneras.

Recordemos que un estado es un objeto. Intentemos pasar al m茅todo setState() un objeto que reemplazar谩 el estado. Reescribimos el m茅todo handleClick() esta manera:

 handleClick() {   this.setState({ count: 1 }) } 

Intentar usar este m茅todo causar谩 el siguiente error: TypeError: Cannot read property 'setState' of undefined . De hecho, de lo que estamos hablando ahora est谩 causando mucha controversia entre los desarrolladores de React, y ahora les voy a mostrar una forma muy simple de resolver este problema, que, a primera vista, puede parecer inusual.

El punto es que cada vez, al crear un m茅todo de clase ( handleClick() en nuestro caso), en el que se planea usar el m茅todo setState() , este m茅todo debe estar asociado con this . Esto se hace en el constructor. El c贸digo del componente despu茅s de esta modificaci贸n se ver谩 as铆:

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }       this.handleClick = this.handleClick.bind(this)   }     handleClick() {       this.setState({ count: 1 })   }     render() {       return (           <div>               <h1>{this.state.count}</h1>               <button onClick={this.handleClick}>Change!</button>           </div>       )   } } export default App 

隆Ahora despu茅s de hacer clic en el bot贸n Change! el n煤mero 1 aparecer谩 encima, no se mostrar谩n mensajes de error.


Al presionar un bot贸n se modifica el estado

Es cierto que el bot贸n result贸 ser "de una sola vez". Despu茅s del primer clic, 0 cambia a 1 y, si vuelve a hacer clic, no pasar谩 nada. En general, esto no es sorprendente. El c贸digo que se llama cuando se hace clic en el bot贸n hace su trabajo, cada vez que cambia el estado a uno nuevo, sin embargo, despu茅s del primer clic en el bot贸n, el nuevo estado en el que se almacena el n煤mero 1 en la propiedad de count no diferir谩 del anterior. Para resolver este problema, considere otra forma de trabajar con el m茅todo setState() .

Si no estamos interesados 鈥嬧媏n cu谩l era el estado anterior del componente, simplemente podemos pasar un objeto a este m茅todo, que reemplazar谩 el estado. Pero a menudo sucede que el nuevo estado de un componente depende del anterior. En nuestro caso, esto significa que, en funci贸n del valor de la propiedad count , que se almacena en la versi贸n anterior del estado, queremos agregar 1 a este valor. En los casos en los que para cambiar el estado, debe tener en cuenta lo que se almacen贸 previamente en 茅l, puede pasar al m茅todo setState() una funci贸n que, como par谩metro, recibe la versi贸n anterior del estado. Puede nombrar este par谩metro como desee, en nuestro caso ser谩 prevState . La adquisici贸n de esta funci贸n se ver谩 as铆:

 handleClick() {   this.setState(prevState => {             }) } 

Puede pensar que en tal funci贸n es suficiente simplemente referirse al estado utilizando una construcci贸n de la forma this.state , pero este enfoque no nos conviene. Por lo tanto, es importante que esta funci贸n acepte la versi贸n anterior del estado del componente.

La funci贸n deber铆a devolver una nueva versi贸n del estado. handleClick() se ver谩 el m茅todo handleClick() para handleClick() este problema:

 handleClick() {   this.setState(prevState => {       return {           count: prevState.count + 1       }   }) } 

Tenga en cuenta que para obtener el nuevo valor de la propiedad count , utilizamos la construcci贸n count: prevState.count + 1 . Puede pensar que una construcci贸n del formulario count: prevState.count++ , pero el operador ++ count: prevState.count++ variable a la que se aplica, esto significar谩 un intento de modificar la versi贸n anterior del estado, por lo que no la usamos aqu铆.

El c贸digo completo del archivo componente en esta etapa se ver谩 as铆:

 import React from "react" class App extends React.Component {   constructor() {       super()       this.state = {           count: 0       }       this.handleClick = this.handleClick.bind(this)   }     handleClick() {       this.setState(prevState => {           return {               count: prevState.count + 1           }       })   }       render() {       return (           <div>               <h1>{this.state.count}</h1>               <button onClick={this.handleClick}>Change!</button>           </div>       )   } } export default App 

Ahora cada clic en el bot贸n aumenta el valor del contador.


Cada clic en el bot贸n aumenta el valor del contador.

Lo que acabamos de descubrir nos abre grandes oportunidades en el desarrollo de aplicaciones React.

Dijimos anteriormente que un componente primario puede, a trav茅s de un mecanismo de propiedad, pasar propiedades de su propio estado a componentes secundarios. Si React detecta un cambio en el estado del componente primario, volver谩 a representar el componente secundario al que se pasa este estado. Parece una llamada al m茅todo render() . Como resultado, el componente secundario reflejar谩 los nuevos datos almacenados en el estado del componente principal.

Resumen


Hoy prepar贸 la aplicaci贸n Todo para seguir trabajando en ella y tambi茅n se familiariz贸 con los mecanismos utilizados en React para cambiar el estado de un componente. La pr贸xima vez se le pedir谩 que ampl铆e las capacidades de la aplicaci贸n de capacitaci贸n utilizando lo que aprendi贸 hoy.

Estimados lectores! 驴Qu茅 le parece el hecho de que el estado de los componentes en React no se puede cambiar directamente sin utilizar mecanismos especiales?

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


All Articles