DEV Community

Sebastián Maciel
Sebastián Maciel

Posted on

Intro a Custom Hooks

Como principiantes en React, hay mucho que abarcar y aprender. Un tema importante es Custom Hooks. Que si bien usamos hooks todo el tiempo, poder crear los nuestros nos va a dar un punto más a la hora de aplicar buenas prácticas y limpiar nuestro código.

Ese enfoque vamos a tomar, refactorizar nuestro código creando hooks personalizados.


Empecemos por las bases

Todo en react básicamente son funciones, la clave está en cómo se escriben. React las reconoce bajo esta norma:

// Componentes | Deben empezar con mayúscula
const MyComponent = (props) => { ...
Enter fullscreen mode Exit fullscreen mode
// Funciones normales | Siempre empiezan con minúsculas
const inputHandler = (e) => { ...
Enter fullscreen mode Exit fullscreen mode
// Hooks | Siempre empiezan con use
const [value, setValue] = useState(); // 
Enter fullscreen mode Exit fullscreen mode

Regla importantísima

El problema que nos surge siempre, es que cuando queremos usar hooks de react en nuestras funciones normales, la regla de hooks nos va a advertir que los hooks solo pueden usarse dentro de componentes de react o de otros hooks.

Y para qué usaríamos un custom hook?

Vamos a limpiar este componente simple:

import React, { useState } from 'react';

const ModeSwitcher = () => { // Componente
  const [darkMode, setDarkMode] = useState(false); // Hook
  const [readMode, setReadMode] = useState(false);

  const toggleDarkMode = () => { // Función
    setDarkMode(!darkMode);
  };

  const toggleReadMode = () => {
    setReadMode(!readMode);
  };

  return (
    <div>
      <button onClick={toggleDarkMode}>
        {darkMode ? 'Light Mode' : 'Dark Mode'}
      </button>

      <button onClick={toggleReadMode}>
        {readMode ? 'Read Mode' : 'Normal Mode'}
      </button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

En este código simple, tenemos dos botones ficticios que simulan un modo "activado/desactivado" para un estado en la aplicación.

Esto es simple y entendible en cómo funciona. Pero si quisiéramos agregar más estados, pecaríamos con la repetición de los useState y las funciones de toggle.

Como refactorización simple, nos vamos a llevar a un hook la lógica de activación y desactivación de un solo switch:

const useSwitch = () => { // empieza con 'use'
  const [switchMode, setSwitchMode] = useState(false);

  const toggleSwitchMode = () => {
    setSwitchMode(!switchMode);
  }

  return [switchMode, toggleSwitchMode];
}
Enter fullscreen mode Exit fullscreen mode

Al ser una función normal, pero empezarla con use, le estamos diciendo a react que es un hook, y por lo tanto nos va a permitir usar otro hook en su interior (useState en este caso).

Esta función realmente puede convivir dentro del mismo componente, pero lo usual es importarlo desde otro archivo, a este hook le haríamos la siguiente modificación en ese caso:

// useSwitch.js
import React, { useState } from 'react';

export default function useSwitch() { //...

Enter fullscreen mode Exit fullscreen mode

Usando el hook

Ahora, simplemente vamos a reemplazar el código interno que teníamos de nuestra app para utilizar nuestro hook, incluso en los dos casos a la vez:

import useSwitch from './useSwitch';

const ModeSwitcher = () => {
  const [darkMode, toggleDarkMode] = useSwitch(); // Nuestro hook
  const [readMode, toggleReadMode] = useSwitch();

  return (
    <div>
      <button onClick={toggleDarkMode}>
        {darkMode ? 'Light Mode' : 'Dark Mode'}
      </button>

      <button onClick={toggleReadMode}>
        {readMode ? 'Read Mode' : 'Normal Mode'}
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

El detalle interesante es que podemos darle el nombre que queramos a cada state y su función para hacer toogle para diferenciarlos:

const [active, switchActive] = useSwitch(); // Por ej.
Enter fullscreen mode Exit fullscreen mode

Para entender lo anterior, leé sobre desestructuración de arrays.

En resumen

Por un lado, notar que eliminamos el useState de nuestro componente principal. Lo cual es un buen refactor, ya que si tenés hooks típicos de react en tus componentes (useState o useEffect), es una buena señal de que podés llevártelos a un custom hook para limpiar el código y refactorizar de manera más profesional tu código.


Si te gustó este post y te gustaría que haga otros custom hooks para profundizar o poder usar otros ejemplo, dejámelo en los comentarios y exploramos.

Gracias!

Top comments (0)