Los componentes de React pueden tener un "estado" interno, un conjunto de pares clave-valor que pertenecen al componente. Cuando el estado cambia, React renderiza el componente nuevamente. Históricamente, el estado solo se podía usar en componentes de clase. Con los ganchos, también puede aplicar el estado a los componentes funcionales.
El enfoque tradicional
Los componentes de la clase React tienen una extensión state
propiedad que posee su estado. Proporcionan un setState()
método que puede utilizar para actualizar el estado, activando una nueva representación.
class MyComponent extends React.Component { state = {value: 1}; this.updateState = () => this.setState({value: (this.state.value + 1)}); render() { return ( <div> <p>{this.state.value}</p> <button onClick={this.updateState}Increment Value</button> </div> ); } }
En este ejemplo, el texto renderizado siempre mostrará el número en el estado del componente. Hacer clic en el botón incrementará el valor.
Conversión a un componente funcional
Con un componente tan sencillo, lo ideal sería reescribirlo como componente funcional. Para hacer esto, necesitará usar el archivo useState () gancho. Se agregaron ganchos en React 16.8; antes de esta versión, no había ningún mecanismo para agregar estado a los componentes funcionales.
Así es como se ve el componente anterior como componente funcional:
import React, {useState} from "react"; const MyComponent = () => { const [value, setValue] = useState(1); return ( <div> <p>{value}</p> <button onClick={() => setValue((value + 1))}>Increment Value</button> </div> ); };
Esto es más corto y más legible que el original basado en clases. A diferencia del componente de clase, no puede acceder a un archivo state
propiedades de instancia o setState()
método. En lugar de, useState()
se llama para establecer el estado y obtener una función de actualización.
UseState Hook Anatomy ()
Los Hooks son una característica de React que le permite "enganchar" la funcionalidad a los componentes funcionales. Dado que las funciones son puras y no tienen instancias, las características que se implementaron originalmente como React.Component
Los métodos de clase no se pueden utilizar directamente. Los enganches le permiten agregar estas características a los componentes sin tener que convertirlos en clases.
El useState()
hook establece una propiedad estatal individual. Devuelve una matriz que contiene dos elementos: el valor del estado actual y una función a la que puede llamar con un nuevo valor para actualizar el estado.
En el ejemplo, estamos usando el asignación de desestructuración de matrices para descomprimir los valores de la matriz en variables con nombres claros. Por convención, el método de establecimiento debe ir precedido de set
ya que toma el lugar de setState()
método de clase.
Vocación useState()
declara una variable de estado, value
en nuestro caso, eso será "retenido" entre llamadas a funciones. Esto significa useState()
se garantiza que devolverá el mismo valor cada vez que lo llame dentro de su componente. Cualquier otro valor de variable se pierde cuando se termina una función; React mantiene los valores de estado internamente para asegurarse de que obtenga los mismos cada vez que se ejecute su función.
Actualización del estado
La función de actualización de estado es solo una función normal. Se utiliza en onClick
controlador para reemplazar el valor del estado actual. El manejo interno de React de los valores de estado asegura que su componente luego se vuelva a renderizar. useState()
proporcionará el nuevo valor, haciendo que el estado cambie.
Hay una diferencia importante con la setState()
de los componentes de la clase: actualizaciones de estado funcional reemplazar el estado, mientras setState()
hace una unión superficial:
const [value, setValue] = useState({foo: "bar", test: {example: "demo"}}); setValue({foo: "foobar"}); // Results in {foo: "foobar"} this.state = {foo: "bar", test: {example: "demo"}}; this.setState({foo: "foobar"}); // Results in {foo: "foobar", test: {example: "demo"}};
En lugar de pasar un nuevo valor de estado directamente, también puede pasar una función a las actualizaciones de estado. Las funciones toman el estado actual como parámetro y deben devolver el nuevo valor de estado. Esto es útil cuando se trabaja con valores editables.
const Checkbox = () => { const [checked, setChecked] = useState(false); const toggle = previous => !previous; return <input checked={checked} onClick={() => setChecked(toggle)} />; };
Esto le ayuda a reutilizar la lógica de conmutación en varios puntos dentro de su componente.
Valores predeterminados
Hay otro punto a tener en cuenta useState()
. El propio gancho acepta un parámetro que establece el valor inicial de la variable de estado. En el ejemplo anterior, el value
se inicializará en 1
. Cuando no especifica un valor, undefined
es usado. Esto corresponde al comportamiento al configurar el state
propiedad de instancia en un componente de clase.
Si pasa una función a useState()
, React lo llamará y usará su valor de retorno como valor de estado inicial.
const MyComponent = () => { const initialState = () => 1; const [value, setValue] = useState(initialState); };
Esta técnica permite la inicialización del estado "perezoso". La función no se llamará hasta que React esté realmente listo para establecer el estado.
El uso de una función también garantiza que el valor del estado inicial se calcule solo una vez. Esto es importante si determinar su estado inicial requiere un cálculo costoso: si lo pasa directamente, el valor se calculará cada vez que el componente se procese, en comparación con una vez en el primer procesamiento si pasa una referencia de función.
const MyComponent = () => { const doSomethingExpensive = () => { // ... } const [value, setValue] = useState(doSomethingExpensive()); const [value, setValue] = useState(doSomethingExpensive); };
La diferencia sutil pero significativa entre los dos useState()
La llamada ilustra la mejora potencial del rendimiento. La primera línea habría realizado la operación costosa en cada llamada de procesamiento, incluso si fuera redundante porque el estado ya estaba inicializado. Esto no sucedería en el segundo caso.
Usando múltiples valores de estado
Tiene un par de opciones cuando usa varios valores de estado en un solo componente funcional. Podría volver a un sistema similar a una clase, utilizando un solo objeto almacenado en el estado:
const MyComponent = () => { const [user, setUser] = useState({id: 1, username: "foobar"}); };
Deberías asegurarte de llamar setUser()
con el usuario actualizado objeto. La sintaxis de propagación es útil de la misma manera que los componentes de la clase:
setUser({...user, username: "example"});
Esto crea un nuevo objeto con las propiedades existentes de user
. Luego actualiza el archivo username
propiedad a su nuevo valor. Es importante crear un archivo nuevo objeto, en lugar de modificar directamente el objeto existente, de modo que la reconciliación del estado de React pueda identificar el cambio.
Alternativamente, puede llamar useState()
varias veces para establecer variables de estado únicas para cada elemento. Este es a menudo el enfoque preferido para los componentes funcionales. Puede facilitar la actualización de valores de estado individuales.
const MyComponent = () => { const [userId, setUserId] = useState(1); const [username, setUsername] = useState("foobar"); };
Las propiedades con estado ahora tienen sus propias variables de estado y funciones de actualización.
Conclusión
Reaccionar useState()
hook hace que los componentes funcionales sean más poderosos al permitirles poseer el estado. Puede establecer un valor inicial, acceder al valor actual con la certeza de que persistirá entre los renderizados y actualizar el estado utilizando una función especialmente provista.
Los componentes funcionales con estado suelen ser más rápidos de escribir que sus homólogos basados en clases. Además, pueden hacer que sea más obvio lo que está sucediendo en su base de código como referencias a state
es setState()
se eliminan a favor de nombres de variables claros. Definitivamente, useState()
proporciona flexibilidad y significa que ya no necesita convertir componentes funcionales en componentes de clase cuando solicita el estado.
Deja una respuesta