DEV Community

Manu Castrillon
Manu Castrillon

Posted on

React Hooks 101

El pasado 25 de octubre durante React conf Dan Abramov y Sophie Alpert anunciaron una nueva propuesta para react: ‘React Hooks’. así como un RFC (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 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.
  const [newToDo, setNewToDo] = useState('');

  function updateNewToDo(e) {
    setNewToDo(e.target.value);
  }
Enter fullscreen mode Exit fullscreen mode
  • useEffect: Recibe una función que va a ser ejecutada cada vez que hay cambios en el DOM.
  const [toDoList, setToDoList] = useState(['Eat healthy', 'Pet my dog']);

  useEffect(() =>{
    document.title = `${toDoList.length} tasks`;
  });
Enter fullscreen mode Exit fullscreen mode
  • useContext: Recibe el objeto retornado por React.createContext y retorna el contexto actual.
  const context = useContext(Context);
Enter fullscreen mode Exit fullscreen mode

Hooks adicionales

  • useReducer
  • useCallback
  • useMemo
  • useRef
  • useImperativeMethods
  • useMutationEffect
  • useLayoutEffect

Hooks personalizados

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

  // 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;
  }
Enter fullscreen mode Exit fullscreen mode

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. 🙅🏻‍♀️:
  import React, { useState } from 'react';

  export default function Search(id) {
    ...
    if(id > 1000) {
      const [superValue, setSuperValue] = useState(id);
    }
  }
Enter fullscreen mode Exit fullscreen mode
  • Llama a los Hooks solo desde function components o custom Hooks 🙅🏻‍♀️:
  import React, { useState, Component } from 'react';

  class Search extend Component {
    ...
    const [superValue, setSuperValue] = useState(this.props.id);
  }
Enter fullscreen mode Exit fullscreen mode
  • Al crear un custom hook, su nombre siempre debe iniciar con la palabra ‘use’ 🙅🏻‍♀️:
  import React, { useState, Component } from 'react';

  function myCustomHook(param) {
    ...
  }
Enter fullscreen mode Exit fullscreen mode

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

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:

Top comments (0)