React Hooks 101
Tags: react, hooks, web
Published: 2020-04-30 21:28:34

El pasado 25 de octubre durante [React conf](https://www.youtube.com/watch?v=dpw9EHDh2bM) Dan Abramov y Sophie Alpert anunciaron una nueva propuesta para react: ‘React Hooks’. así como un [RFC](https://github.com/reactjs/rfcs/pull/68) (Request for comments) para esta misma propuesta, con la cual el objetivo es que los desarrolladores de React después de leer la propuesta y experimentar con ella, brinden su retroalimentación.

## ¿Qué está mal con React?

La propuesta de React Hooks busca abordar 3 problemas que tiene React:

### 1. Reutilización de la lógica entre componentes

Para solucionar este problema, inicialmente se propusieron los mixins, que [fueron deprecados](https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html) en 2016 porque causaba más problemas de los que estaban resolviendo. En este momento, para solucionar este problema se utilizan utilizan 2 estrategias: ‘High order components’ que lo que hacen básicamente es tener un componente contenedor el cual contiene otros componentes, la función del componente contenedor es enviarle a los componentes que contiene el estado que necesitan para su renderización; la otra alternativa es ‘Render props’ que lo que permite es compartir información entre componentes enviando funciones como props.

Estas alternativas implican agregar mucho código a la aplicación e incluso modificar la estructura del proyecto y como consecuencia, también nos forman un ‘Wrapper Hell’ por la cantidad de componentes que toca anidar para lograr compartir la lógica que queremos.

### 2. Componentes gigantes

La lógica suele no estar distribuida coherentemente, en un mismo método del ciclo de vida podemos tener varias líneas de código de lógica que no tiene nada que ver una con la otra y la lógica que si está directamente relacionada, termina estando repartida entre diferentes métodos.

### 3. Uso de clases

Para aprender react debemos también aprender cómo funcionan las clases en Javascript (esto implica también el funcionamiento de this), lo cual le agrega más complejidad al proceso de aprendizaje. Y no solo es difícil para las personas... para las máquinas también es difícil aprender clases, porque cuando deben minificar el código no lo hacen de la mejor manera.

Otro problema a la hora de desarrollar es que no tenemos claro cuándo desarrollar function components (stateless) o class components (stateful), porque si desarrollamos un function component y en algún momento del desarrollo surge la necesidad de que tenga estado, lo debemos refactorizar totalmente para convertirlo en clase, y para evitarnos la fatiga… terminamos dejando todos nuestros componentes como clases.

## ¿Cómo lo solucionamos?

Este problema es causado porque la forma más simple que tiene React para manejar un componente que tenga estado es usando clases (y ya vimos que hacerlo de esta forma nos puede generar problemas en algunos casos).

Para solucionar estos problemas… llegan 🥁 **Hooks** 🎉

## ¿Que son los Hooks?

Los Hooks son funciones que permiten organizar la lógica en los componentes de forma aislada y ‘engancharlos’ al estado y ciclo de vida del componente. Estos, nos permiten utilizar todos los features de react y tener componentes con estado sin necesidad de crear clases.

React provee algunos Hooks, pero nosotros también podemos crear nuestros nuestros propios Hooks personalizados.

## ¿Cuales Hooks provee React?

### Hooks básicos

- **useState:** Retorna un valor con estado y una función para actualizarlo.

  ```javascript
  const [newToDo, setNewToDo] = useState('');

  function updateNewToDo(e) {
    setNewToDo(e.target.value);
  }
  ```

- **useEffect:** Recibe una función que va a ser ejecutada cada vez que hay cambios en el DOM.

  ```javascript
  const [toDoList, setToDoList] = useState(['Eat healthy', 'Pet my dog']);

  useEffect(() =>{
    document.title = `${toDoList.length} tasks`;
  });
  ```

- **useContext:** Recibe el objeto retornado por React.createContext y retorna el contexto actual.

  ```javascript
  const context = useContext(Context);
  ```

### Hooks adicionales

- useReducer
- useCallback
- useMemo
- useRef
- useImperativeMethods
- useMutationEffect
- useLayoutEffect

### Hooks personalizados

También podemos crear nuestros propios Hooks compartir su lógica entre componentes 🙌

  ```javascript
  // function component
  export default function ToDoApp() {

    const [newToDo, setNewToDo] = useState('');
    const magicNumber = useMagicNumber(newToDo);
    ...
  }

  // custom hook
  function useMagicNumber(param) {
    const [number, setNumber] = useState();
    var date = new Date();
    var day = date.getDate();
    var month = date.getMonth()+1;

    useEffect(() => {
      setNumber(param.length * day + month / 12.34);
    });

    return number;
  }
  ```

### Reglas de los Hooks 👮‍♂️

Para poder utilizar los Hooks hay que seguir un par de reglas:

- Solo llama a los Hooks en el ‘Top Level’ del componente, no los llames en ciclos, condicionales, o funciones anidadas, esto asegura que los Hooks se van a llamar siempre en el mismo orden cuando la aplicación es renderizada.
  🙅🏻‍♀️:

  ```javascript
  import React, { useState } from 'react';

  export default function Search(id) {
    ...
    if(id > 1000) {
      const [superValue, setSuperValue] = useState(id);
    }
  }
  ```

- Llama a los Hooks solo desde function components o custom Hooks
  🙅🏻‍♀️:

  ```javascript
  import React, { useState, Component } from 'react';

  class Search extend Component {
    ...
    const [superValue, setSuperValue] = useState(this.props.id);
  }
```

- Al crear un custom hook, su nombre siempre debe iniciar con la palabra ‘use’
  🙅🏻‍♀️:

  ```javascript
  import React, { useState, Component } from 'react';

  function myCustomHook(param) {
    ...
  }
  ```


*Recomendación:* Utilizar *eslint-plugin-react-hooks* un plugin para eslint que te obliga a seguir las reglas anteriormente mencionadas. Para el caso de la tercera regla, lo que hace el plugin es asumir que todas las funciones que inician con use son hooks.

## ¿Cuándo utilizar Hooks?

Las clases van a continuar existiendo en React y no hay planes de deprecarlas, ambos tipos de componentes pueden coexistir sin ningún problema en la misma aplicación. La recomendación es empezar a utilizar Hooks en todos nuestros nuevos componentes, no se recomienda reescribir los componentes antiguos ya que puede ser un poco confuso migrar la lógica, además, debemos tener en cuenta el hecho de que los Hooks aún se encuentran en versión alpha y podrían tener algunos cambios.

Hooks aún no cumple con todos los casos de uso que podría tener un componente de React ni tiene equivalentes para algunos métodos del ciclo de vida, sin embargo, ya están trabajando en esto y la visión es que a futuro los hooks puedan reemplazar todos los métodos del ciclo de vida. Para el caso de HOC y Render props, siguen siendo útiles para trabajar algunos casos de uso muy concretos, pero la mayoría de ellos ya es posible hacerlos con Hooks.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/imcrni2p8gbrod1s94f3.jpeg)

Para finalizar… Yo no tengo mucha experiencia desarrollando en React (apenas estoy aprendiendo) y siento que se me ha hecho sencillo aprenderlo utilizando Hooks, para quienes llevan más tiempo manejando React, no se que tan brusco será el cambio, pero personalmente me gusta el concepto de encapsular toda la lógica que esta relacionada porque considero que es lo más limpio a la hora de hacer código, haciéndola mas fácil de reutilizar y testear.

Me gustaría conocer su experiencia de cómo fue cambiar de class components a hooks.

**Recursos:**

- [Documentación de React Hooks](https://reactjs.org/docs/hooks-intro.html)
- [React Hooks RFC](https://github.com/reactjs/rfcs/pull/68)