Índice:
Descripción
useState nos permite agregarle un estado a un componente funcional.
Retorna un par de valores:
- el estado.
- una función para poder actualizarlo.
const [count, setCount] = useState(0);
En nuestro ejemplo anterior, count
es nuestro estado y está inicializado con el valor 0
y setCount
es nuestra función para poder actualizarlo.
Dato:
Observemos que estamos haciendo una destructuración de un array cuando ejecutamos el hookuseState
, lo que nos da la posibilidad de poder llamar a nuestro estado y función para actualizarlo como querramos. Por convención la función debe comenzar conset
.
useState
espera un solo argumento, el cual sería el valor por defecto que tendría nuestro estado. A diferencia del estado en los componentes de clases, nuestro estado pueden ser strings, numbers, etc.
import { useState } from 'react';
const [count, setCount] = useState(0);
const [text, setText] = useState('Hi there!');
const [user, setUser] = useState({
name: 'Denis',
job: 'Frontend Enginner'
});
const [shoppingList, setShoppingList] = useState([
{
item: 'laptop',
price: 900,
currency: '€'
}
]);
Volver al índice
Diferencia con this.setState
Tenemos que tener en cuenta a la hora de actualizar nuestro estado que a diferencia del this.setState
de los componentes de clase donde el estado es siempre un objeto y podemos actualizar una propiedad del mismo directamente sin afectar al resto, que nuestra función devuelta por el hook useState
va a reemplazar por completo nuestro estado por el valor que nosotros le pasemos, por ende, si nuestro estado por ej, es un objeto y nosotros quisiéramos actualizar una sola propiedad, deberíamos pasarle la propiedad actualizada y además, el resto de sus propiedades.
Class component
// ...
constructor(props) {
super(props);
// Definimos nuestro estado
this.state = {
count: 0,
text: "class text"
};
this.onClick = this.onClick.bind(this);
}
onClick() {
// Destructurando obtenemos el valor de count
const { count } = this.state;
// Actualizamos el valor de count sin afectar
// el valor de text
this.setState({ count: count + 1 });
}
// ...
Functional component
// ...
// Destructurando obtenemos los valores de count y text
const [{ count, text }, setState] = React.useState({
count: 0,
text: "functional text"
});
const onClick = () => {
// Actualizamos el valor de count y mantenemos el de text
setState({
count: count + 1,
text
});
// También podríamos actualizar nuestro estado haciendo
// uso de una función. (Recomendado)
setState(prevState => ({
...prevState,
count: count + 1
}));
}
// ...
Dato:
Si asetState
solo le pasariamos el valor decount
, perderíamos todo rastro detext
, dejaría de existir.
Ejemplo en CodeSandbox
Volver al índice
Lazy initial state
Si el valor por defecto que queremos asignarle a nuestro estado es el resultado de un calculo costoso, podemos utilizar el lazy initial state, es decir, es vez de pasarle nuestro estado inicial, lo que hacemos es pasarle una función que lo calcule, esto se ejecutará una sola vez en el render inicial.
function getExpensiveState() {
// Calculo costoso
}
// Nuestro componente va a realizar el calculo costoso
// en cada render aunque no utilice su valor más allá del
// primer render.
function ComponentWithoutLazy() {
const [state, setState] = React.useState(getExpensiveState());
// ...
}
// Ahora nuestro componente solo va a realizar el calculo
// costoso en el primer render.
function ComponentWithLazy() {
const [state, setState] = React.useState(() => getExpensiveState());
// ...
}
Ejemplo en CodeSandbox
Volver al índice
Functional updates
Cuando nuestro componente es simple y no contiene muchas actualizaciones de estado ejecutadas por diversos eventos, cambios de props, etc, no vamos a tener problemas actualizando nuestro estado seteando el nuevo directamente.
function Counter() {
const [count, setCounter] = React.useState(0);
function onClick() {
setCounter(count + 1);
}
// Code
}
Pero cuando nuestro componente comienza a manejar más lógica y este estado es actualizado en distintas oportunidades por distintos eventos, acciones, etc. Lo mejor y más recomendable, es utilizar una función para actualizar nuestro estado con setState
, de esta manera:
function Counter() {
const [count, setState] = React.useState(0);
function onClick() {
setState(prevState => ({
...prevState,
count: prevState + 1
}));
}
// Code
}
Por qué? Porque utilizando una función nos aseguramos de tener el último valor de nuestro estado para poder actualizarlo en consecuencia y evitar inconsistencias o valores erróneos.
Ejemplo en CodeSandbox
Top comments (1)
Many early birds have already started using this custom hooks library
in their ReactJs/NextJs project.
Have you started using it?
scriptkavi/hooks
PS: Don't be a late bloomer :P