Domina los Hooks de React: Los 7 más importantes que debes conocer
Introducción
Si estás construyendo aplicaciones en React
, los Hooks
son el equivalente a tener en tus manos herramientas de construcción de alta calidad. Con ellos, puedes crear aplicaciones duraderas y de alta calidad de manera eficiente y sin esfuerzo. Pero, ¿sabes cuáles son los 7 Hooks más importantes de React?
. En este artículo, descubrirás cómo utilizarlos, para qué sirven y por qué deberías incluirlos en tus proyectos
. Prepárate para llevar tus habilidades de desarrollo al siguiente nivel.
¿Qué son los Hooks?
Los hooks
son una característica de React
, que permiten a los desarrolladores utilizar el estado
y otras características de React en componentes. Con los hooks, los desarrolladores pueden reutilizar la lógica de estado y efectos secundarios en diferentes componentes, lo que hace que el código sea más fácil de mantener y menos propenso a errores.
En este articulo aprenderas sobre los siguientes hooks:
- useState: Este hook permite que un componente tenga un estado interno y que se actualice cada vez que se llama a la función
setState
. - useEffect: Este hook se utiliza para manejar los
efectos secundarios
de un componente, como actualizar elDOM
o llamar a unaAPI
. Se llama después de que se renderice el componente y puede actualizar el estado o las props. - useContext: Este hook permite a un componente acceder a un
contexto
proporcionado por un componente padre. - useReducer: Este hook permite a un componente manejar el estado mediante la implementación de una
función reductora
que recibe el estado actual, una acción y devuelve un nuevo estado. - useRef: Este hook se utiliza para crear una
referencia mutable
que se puede mantener durante toda la vida útil del componente. - useCallback: Este hook permite a un componente crear una
función memorizada
que puede ser pasada como una prop sin necesidad de volver a renderizar el componente. - useMemo: Este hook permite a un componente
memorizar
el resultado de una función costosa y reutilizarlo en futuras renderizaciones.
useState
El hook useState
es probablemente el más utilizado de todos los hooks de React
. Permite a los desarrolladores almacenar y actualizar el estado dentro de un componente. En otras palabras, useState permite que los componentes tengan una memoria interna
que pueden usar para almacenar y cambiar datos.
¿Comó utilizar useState?
Para utilizar useState
, es necesario importarlo desde la biblioteca de React. Luego, se puede llamar dentro de un componente funcional
de React y proporcionar un valor inicial para el estado. Este valor inicial puede ser cualquier tipo de dato válido en JavaScript
.
useState devuelve un array con dos elementos: el primero es el valor actual
del estado y el segundo es una función
para actualizar el estado. Esta función suele llamarse 'setNombreDelEstado', comenzando con la palabra set
seguida del nombre del estado.
Ejemplo de uso de useState
import { useState } from "react";
const Counter = () => {
// inicializamos el estado con un valor de 0
const [count, setCount] = useState(0);
return (
<div>
<p>Haz hecho {count} clicks</p>
<button onClick={() => setCount(count + 1)}>Cliqueame</button>
</div>
);
};
En este ejemplo, useState
se utiliza para almacenar el estado del contador dentro del componente Counter. El valor inicial de count
es 0, y cada vez que el botón se presiona, el estado se actualiza utilizando la función setCount()
. En este caso, estamos tomando el valor de count
y luego le sumamos 1.
¿Por qué utilizar useState en React?
Deberías incluir useState
en tus componentes de React
porque es la forma más sencilla y efectiva de agregar y administrar el estado local en un componente funcional
.
En resumen, incluir useState
en tus componentes
te permite agregar y administrar el estado local de una manera fácil y efectiva, lo que te permite construir componentes interactivos y dinámicos en tus aplicaciones de React.
useEffect
El hook useEffect
se utiliza para realizar efectos secundarios
dentro de un componente. Esto puede incluir la actualización de un componente después de que cambie el estado, la ejecución de una función
después de que se monte o desmonte un componente, o la recuperación de datos de una API
.
Parametros necesarios en useEffect
Dentro del hook useEffect
, es necesario establecer dos parámetros. El primero es una función
que contiene el efecto
que se va a ejecutar. El segundo es un array de dependencias
que determinará cuándo se volverá a ejecutar el efecto.
Cuando alguno de los valores en el array cambie, el efecto
se volverá a ejecutar. Si no se especifica el array, el efecto se volverá a ejecutar con cada cambio en el componente. Si se especifica un array vacío
, este tan solo se ejecutará la primera vez que el componente se renderice.
Ejemplo de uso de useEffect
import { useEffect, useState } from "react";
const UserList = () => {
const [users, setUsers] = useState([]);
useEffect(() => {
// realizamos petición HTTP dentro del useEffect
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((data) => setUsers(data));
}, []);
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
En este ejemplo, useEffect
se utiliza para recuperar los datos de una API
y almacenarlos en el estado creado con useState
llamado 'users'. El segundo parámetro de useEffect
es un array vacío, lo que significa que la función se ejecutará solo una vez, cuando se monte el componente.
Conclusiones y precauciones a tomar en cuenta sobre el uso de useEffect
En general, useEffect
es un hook
muy útil que nos permite manejar efectos secundarios
en nuestros componentes. Nos permite realizar operaciones de manera segura y efectiva, como realizar solicitudes de red
, actualizar el DOM
o manejar la lógica de la aplicación.
Es importante tener precauciones al usar useEffect
. Debemos asegurarnos de que los efectos secundarios no sean destructivos, depurarlos adecuadamente y considerar el rendimiento al usarlos. Además, debemos tener en cuenta las dependencias y evitar bucles infinitos
al actualizar el estado dentro del efecto.
useContext
El hook useContext
se utiliza para acceder al contexto
dentro de un componente. El contexto es una forma de pasar datos a través de la jerarquía de componentes
sin tener que pasar props
manualmente en cada nivel.
Crear Context
Para utilizar useContext
, primero se debe crear un contexto utilizando el método createContext
. Este contexto puede contener cualquier tipo de datos
, como un objeto
, una cadena de texto
, un número
, etc.
import { createContext } from "react";
// creamos y exportamos el contexto
export const MyContext = createContext();
Crear Provider
El Provider
es un componente
que se utiliza para proporcionar datos del contexto
a todos los componentes que los necesiten. Este componente envuelve a todos los componentes que necesitan acceder a los datos del contexto
.
El Provider
recibe la propiedad children
, que son los componentes que envolverá y a los que les dará acceso al contexto. Por último, retorna el contexto previamente creado y utiliza la propiedad Provider
de ese contexto. Dentro del 'Provider' se coloca el 'children' recibido por props
. Además, el 'Provider' recibe una propiedad value
, que son los valores que dará acceso a todos los componentes que envuelve.
import { createContext } from "react";
// creamos y exportando el contexto
export const MyContext = createContext();
// componente que exportara el "Provider" del contexto
export const MyContextProvider = ({ children }) => {
const users = [{ name: "Carlos" }, { name: "Tomás" }, { name: "Juan" }];
return <MyContext.Provider value={{ users }}>{children}</MyContext.Provider>;
};
Colocar Provider
Es común colocar este Provider
en el punto de entrada
de nuestra aplicación, envolviendo todos los demás componentes. De esta manera, todos los componentes que formen parte de nuestra aplicación tendrán acceso al contexto
proporcionado por el Provider
.
import ReactDOM from "react-dom/client";
import { MyContextProvider } from "./context/MyContextProvider"; // provider
import { MyComponent } from "./MyComponent"; // componente hijo
import "./styles.css";
// envolvemos el componente con el provider
ReactDOM.createRoot(document.getElementById("root")).render(
<MyContextProvider>
<MyComponent />
</MyContextProvider>
);
Acceder al contexto mediande useContext
Para acceder a los datos proporcionados por el contexto
en un componente específico, debemos utilizar el hook useContext
. A continuación, se muestra un ejemplo de cómo se utiliza este hook:
import { useContext } from "react";
// importamos el contexto
import { MyContext } from "./context/MyContext";
export const MyComponent = () => {
// utilizamos useContext y mandamos como parametro el contexto que queramos usar
const { users } = useContext(MyContext);
return (
<ul>
{users.map((user) => (
<li>
<h3>{user.name}</h3>
</li>
))}
</ul>
);
};
En este ejemplo, se utiliza el hook useContext
para acceder a los datos proporcionados por el contexto
llamado MyContext
. En particular, se obtiene el array de objetos
'users' que se encuentra dentro del contexto. Luego, en el componente, se renderiza el nombre de todos los usuarios del array.
useReducer
UseReducer
es un hook
que se utiliza para manejar el estado
de una aplicación en la que los cambios son complejos y requieren una función separada
para su actualización. Esta función se llama reducer
y se encarga de actualizar el estado de la aplicación en función de la acción
realizada en la interfaz de usuario
.
Aunque useReducer
se utiliza de manera similar a useState
, la diferencia principal es que useReducer se basa en el patrón de diseño
reducer
, comúnmente utilizado en programación funcional.
Sintaxis de useReducer
import { useReducer } from "react";
const [state, dispatch] = useReducer(reducer, initialState);
- state: Es el
estado actual
de la aplicación. - dispatch: Es una
función
que se utiliza paraactualizar el estado
de la aplicación. - reducer: Es una
función
que toma elestado actual
, laacción realizada
y devuelve unnuevo estado
actualizado. - initialState: Es el
estado inicial
de la aplicación.
Función reducer
La función reducer
es una parte fundamental del hook useReducer
. Esta función recibe dos argumentos: el estado actual
de la aplicación y una acción
. La función reducer procesa esta acción y devuelve un nuevo estado
actualizado de la aplicación.
const reducer = (state, action) => {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
throw new Error();
}
};
En este ejemplo, se utiliza la función reducer
para procesar distintas acciones
según su tipo, y se hace uso de una estructura switch
para ello. En cada caso de acción, se lleva a cabo algún tipo de procesamiento
en el estado actual
y se devuelve un nuevo estado
actualizado.
El último caso de la estructura switch es el default
, que se utiliza para manejar cualquier acción que no haya sido contemplada en los casos anteriores. En este caso, simplemente se devuelve el estado actual
sin cambios.
Utilizando useReducer
Entonces, para utilizar useReducer
, se debe establecer previamente el valor inicial del estado. Luego, se debe definir el reducer (función encargada de cambiar el estado) que se utilizará. Finalmente, se debe llamar a la función dispatch
cada vez que se desee actualizar el estado.
A continuación, se muestra un ejemplo de código para llevar a cabo todo esto:
import { useReducer } from "react";
// estado inicial del reducer
const initialState = { count: 0 };
// funcion reducer
const reducer = (state, action) => {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
throw new Error();
}
};
export const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<h2>Count: {state.count}</h2>
<button onClick={() => dispatch({ type: "increment" })}>Increment</button>
<button onClick={() => dispatch({ type: "decrement" })}>Decrement</button>
</div>
);
};
En este ejemplo se presenta un componente llamado Counter
que utiliza la función useReducer
para gestionar su estado interno. Este componente implementa un 'contador', cuyo valor inicial se establece en cero mediante la constante initialState
.
La función reducer
es responsable de actualizar el estado del contador en función de la acción
realizada. En este caso, hay dos acciones posibles: la acción increment
, que aumenta el contador en 1, y la acción decrement
, que lo disminuye en 1.
useRef
useRef
es un hook que permite crear una referencia mutable
que persiste durante el ciclo de vida de un componente. Esto puede ser útil para acceder directamente a elementos del DOM
, guardar valores que no cambian pero que necesitan ser almacenados de alguna manera, o para guardar referencias a valores que se utilizan en efectos o en otras partes del componente.
Ejemplo de uso real
Uno de los usos más comunes de useRef
es para acceder directamente a un elemento del DOM
y realizar alguna operación en él. Por ejemplo, si deseamos que un botón tenga el foco cuando un componente se renderiza, podemos usar useRef para almacenar una referencia al elemento del botón y luego usar current
para asignarle el foco:
import { useRef, useEffect } from "react";
export const MyComponent = () => {
// creamos useRef con un valor inicial de 'null'
const buttonRef = useRef(null);
useEffect(() => {
// activamos el "focus" del botón
// al renderizarseel componente
buttonRef.current.focus();
}, []);
return (
<div>
<button ref={buttonRef}>Haz clic aquí</button>
</div>
);
};
En este ejemplo, creamos una referencia mutable llamada buttonRef
utilizando useRef
, la cual se inicializa con el valor 'null'. Luego, en el efecto, utilizamos buttonRef.current
para acceder directamente al elemento de botón y llamar al método focus()
en él. Finalmente, en la propiedad ref
del elemento button
, debemos asignarle el valor de buttonRef
, lo que permite a React asignar el elemento a la propiedad current
de nuestra referencia y así mantener su referencia actualizada.
Al utilizar useEffect
con un array de dependencias vacío, éste solo se ejecutará la primera vez que se renderice el componente. Esto permitirá que se aplique el 'focus' sobre el botón en ese momento.
useCallback
useCallback
es un hook que ayuda a mejorar el rendimiento de los componentes que utilizan funciones como propiedades
.
Cuando creamos una nueva instancia
de una función en cada renderizado de un componente, esto puede generar una sobrecarga innecesaria y afectar el rendimiento
del sitio web
. Utilizando useCallback
, podemos crear una instancia de la función solo cuando cambia una de sus dependencias
, lo que nos ayuda a evitar esta sobrecarga y mejorar el rendimiento.
Utilizar useCallback
Para utilizar useCallback
, simplemente envuelve la función
que deseas optimizar con useCallback y proporciona las dependencias como un arreglo de dependencias
. La función solo se volverá a crear si alguna de sus dependencias cambia.
import { useState, useCallback } from "react";
export const MyComponent = () => {
// inicializamos el estado en '0'
const [count, setCount] = useState(0);
// memorizamos la función
const handleClick = useCallback(() => {
console.log(`El contador es ${count}`);
}, [count]);
return (
<div>
<p>Contador: {count}</p>
<button onClick={handleClick}>Incrementar contador</button>
</div>
);
};
En este ejemplo, utilizamos useCallback
para crear una instancia de la función handleClick
solamente cuando la variable count
cambie. Pasamos 'count' como la única dependencia del hook
, lo que significa que 'handleClick' solo se volverá a crear si 'count' cambia, evitando así re-renderizados
innecesarios.
Utilizando useCallback
, podemos mejorar significativamente el rendimiento de nuestros componentes y garantizar que nuestro sitio web tenga una mejor experiencia de usuario.
useMemo
Cuando utilizamos useMemo
, podemos memorizar
el resultado de una función
y almacenar su valor en una constante. De esta manera, si el componente se vuelve a renderizar, React
comprueba si los valores de entrada de la función han cambiado. Si no hay cambios, useMemo
devuelve el valor memorizado sin tener que ejecutar nuevamente la función, lo que puede mejorar significativamente el rendimiento de la aplicación.
Caso de uso real
Un caso frecuente en el cuál se utiliza useMemo
es cuando se necesita ordenar una lista. En lugar de ordenar la lista en cada renderizado, useMemo
permite memorizar
la lista ordenada y evitar cálculos innecesarios. A continuación, se muestra un ejemplo ilustrativo:
import { useMemo } from "react";
const UserList = ({ users }) => {
// solo se vuelve a ejecutar cuando la propiedad 'users' cambie
const sortedUsers = useMemo(() => {
return [...users].sort((a, b) => a.name.localeCompare(b.name));
}, [users]);
return (
<ul>
{sortedUsers.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
En este ejemplo, hemos utilizado useMemo
para memorizar la lista de usuarios ordenada alfabéticamente según el valor de la propiedad name
. La función que realiza esta operación se ejecutará únicamente cuando el array de 'usuarios' cambie, y su resultado se almacenará en la constante sortedUsers
.
Si el componente se renderiza de nuevo por cualquier otra razón, useMemo
devolverá directamente la lista ordenada que se ha memorizado, en lugar de ejecutar nuevamente la función, ahorrando así recursos y mejorando el rendimiento del componente.
Conclusiones
En este artículo, hemos explorado algunos de los hooks
más importantes de React
: useState
, useEffect
, useContext
y useReducer
. Estos hooks proporcionan herramientas poderosas para crear componentes interactivos, manejar efectos secundarios y compartir datos entre componentes.
El hook useState
es ideal para manejar el estado interno de un componente funcional, permitiendo almacenar y actualizar datos de manera sencilla. Por otro lado, useEffect
es útil para manejar efectos secundarios como llamadas a APIs
, actualizaciones del DOM
y más.
El hook useContext
nos permite acceder al contexto dentro de un componente, evitando la necesidad de pasar datos manualmente a través de props. Y finalmente, useReducer
es útil para manejar estados más complejos en los que se requiere una función separada para actualizar el estado.
Estos hooks
son herramientas esenciales en el kit de desarrollo de React
y te permiten escribir código más limpio, modular y fácil de mantener. A medida que te familiarices con estos hooks y los incorpores en tus proyectos, verás cómo mejoran la eficiencia y calidad de tus aplicaciones.
En resumen, los hooks de React
son una característica poderosa que te ayudará a construir aplicaciones más eficientes y de alta calidad. ¡No dudes en explorar más sobre ellos y experimentar con su uso en tus proyectos!