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 ​​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 31. Taller. TODO aplicación. Etapa número 5


Original

▍Trabajo


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.

▍Solució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 ​​en 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 ​​en 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