useState | Entrevistas de React
Tags: react, javascript, interview, beginners
Published: 2023-10-04 00:38:39

Lo importante sobre los hooks de react para tener en cuenta en una entrevista, es potencialmente poder saber y responder tres puntos esenciales:

- Qué son en simples palabras
- Qué problemas resuelven
- Un ejemplo simple de implementación

En esta ocasión, nos toca el manejo de estado.

---

## useState

### Qué es?

Este hook es básicamente una forma de declarar una variable que para React va a tener un significado especial: 

> Cada vez que cambiemos el valor de esta variable, React va a detectar esa actualización y disparar un rerender del componente en el que se encuentra. O sea, volver a crear este componente, volver a pintarlo en el navegador.

---

#### Qué problema resuelve?

La idea es tener una manera de que React reaccione ante un cambio que realicemos en una variable. Veamos un ejemplo, sin React:

```jsx
// Inicializamos una variable que vamos a usar de contador:
let counter = 0

// Actualizamos el valor de esa variable de manera típica:
counter++
```

Con el ejemplo anterior, efectivamente vamos a aumentar el contador. Pero React no va a estar al tanto de ese cambio. Por lo que si usamos esa variable para mostrar algo en el navegador, el cambio no se va a reflejar.

Ahora, usemos useState:

```jsx
const [ counter, setCounter ] = useState(0)
```

Para entender lo que pasa, tenemos que tener bien sabidos dos conceptos de JavaScript:

- Funciones ([Documentación](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions)).
- Desestructuración de Arrays ([Documentación](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)).

---

Estos dos conceptos nos dejan entender que `useState` es básicamente una función que React nos brinda que tiene dos características simples:

- Es una función que puede tomar como parámetro, una de dos cosas:
    - Un valor que inicializa la variable `counter` (lo más común)
    - Una función de inicialización (menos común, más sobre esto luego)
- Y a su vez, nos devuelve un array con dos elementos:
    - La variable con el valor que nos interesa.
    - Una función que sirve para actualizar esa variable.

La forma más simple de usarla es:

```jsx
setCounter(1)
```

Esto va a lograr que React vuelva a crear el componente donde estemos usando este hook, y a su vez actualizar el valor de la variable `counter` a 1.

Veamos un ejemplo de componente real:

```jsx
import { useState } from "react";

const MyCounter = () => {
  const [counter, setCounter] = useState(0);

  return (
    <>
      <button onClick={() => setCounter(counter + 1)}>Add</button>
      <p>{counter}</p>
    </>
  );
};
```

Este componente simple cumple con dos tareas:

- Mostrar un botón que al hacer click ejecuta el `setCounter`:
    - `setCounter` recibe el valor actual de `counter` y lo incrementa.
    - React entiende que hubo un cambio en la UI y dispara un rerender.
- Un paragraph que muestra el valor de la variable counter.

---

### Casos especiales

Lo interesante de leer las librerías es que vas descubriendo cosas como por ejemplo, que la función `setCounter` acepta un valor para actualizar `counter`, pero también se le puede pasar una función.

De esta función podemos recibir un parámetro que es realmente el último valor de `counter`. Realmente, al inicio de nuestro camino en React es probable que no nos haga mucha diferencia utilizar un método u otro:

```jsx
<button onClick={() => setCounter(counter + 1)}>
  Add
</button>

// O también

<button onClick={() => setCounter((currentCounter) => currentCounter + 1)}>
  Add
</button>
```

Solamente cuando nos encontramos utilizando este `setCounter` en ocasiones o en conjunto con operaciones que lleven un cierto tiempo en completarse, como acciones asíncronas, es cuando necesitamos realmente el último valor actualizado de `counter`. Son esos detalles que nos vuelven locos y que terminamos entendiendo de una manera u otra. No hay que pretender entender esto en los primeros momentos del proceso de aprendizaje.

La regla es: recordar que nuestro valor está tardando en actualizarse, o que se está actualizando mal debido a que no estamos tomando el último valor realmente disponible.

---

### Función inicializadora

En otros momentos, necesitamos inicializar el primer estado de nuestro `useState` con algún valor que quizás lleve un tiempo en resolver, como una llamada a un endpoint, algún cálculo matemático o incluso leer algo de localStorage. Algo simple pero que lleve un tiempo.

Es muy poco probable tener que usar esto, realmente. Pero `useState` también acepta una función que sirve para inicializar solamente una vez y al inicio del renderizado del componente, el valor de nuestro estado. Sería algo así:

```jsx
const processedUserInfo = getUserComplexInfo()

const [userInfo, setUserInfo] = useState(() => processedUserInfo)
```

Lo que va a hacer esto es: llenar nuestro `userInfo` con la información calculada o procesada **una sola vez**. Pagamos el precio de la tardanza la primera vez y listo. Luego podemos actualizar y rerenderizar el componente todas las veces siguientes, sin tener que volver a procesar la info de `getUserComplexInfo`.

> Normalmente es raro utilizar esto, pero existe por una razón. Como regla es bueno medir la performance de tu componente. Realmente si requiere esta manera de inicializar el estado entonces considerar usarlo. Pero optimizar por el mero hecho de optimizar, puede salir más caro de lo que parece.

Por último: si tu componente tiene muchos `useState`, es muy probable que necesites usar un `useReducer` para simplificar el manejo de estado de tu componente. Así vas a ganar practicidad en la lectura del código y evitar la repetición y malas prácticas.

---

Si te gustó este contenido y estás iniciando o llevás un tiempo en React y te gustaría que escriba sobre algún otro tema en particular, dejame tu comentario.

Voy a seguir atacando estos temas básicos sobre React de todas maneras.

Gracias por el tiempo!

Seba.