useMemo
Un problema común en aplicaciones desarrolladas con react es controlar lo que sucede cuando ocurren las renderizaciones de la interfaz gráfica. Es necesario ser conscientes de que cada cambio de estado, como el que ocurre al usar el hook useState, dispara una nueva renderización de toda la interfaz.
Para ejemplificar este problema, veamos el siguiente ejemplo:
import { useState } from "react";
export const UseMemoProblem = () => { const options = ["Option 1", "Option 2", "Option 3"]; const [, setOption] = useState(0);
const data = getData();
return ( <> {options.map((option, index) => ( <button key={option} onClick={() => setOption(index)}> {option} </button> ))}
<p>{data}</p> </> );};
const getData = () => { console.log("Getting data from problem... ");
let data = 0; for (let i = 0; i < 100000; i++) { data += i; }
return data;};En este ejemplo estamos usando el hook useState para escoger entre 3 opciones. El problema es que cada que seleccionamos uno de los botones ocurre un cambio de estado, y, por tanto, se renderiza de nuevo el componente.
Podemos notar que la función getData se ejecuta cada vez que se renderiza el componente. En primera instancia, esto no parece un problema tan grave, pero si se diera el caso en el que getData fuese una función demasiado pesada o que hiciera fetching de datos, estaríamos consumiendo recursos innecesariamente.
Aquí es donde entra en escena el hook useMemo. Este hook lo que nos permite es memorizar el resultado de una función entre renderizaciones. Tiene un comportamiento similar al hook useEffect, recibe como parámetro un callBack y un array de dependencias, con el que controlamos la ejecución de la función.
Nuestro componente quedaría de la siguiente forma:
import { useMemo, useState } from "react";
export const UseMemoExample = () => { const options = ["Option 1", "Option 2", "Option 3"]; const [, setOption] = useState(0);
const data = useMemo(() => getData(), []);
return ( <> {options.map((option, index) => ( <button key={option} onClick={() => setOption(index)}> {option} </button> ))}
<p>{data}</p> </> );};
const getData = () => { console.log("Getting data from example XD... ");
let data = 0; for (let i = 0; i < 100000; i++) { data += i; }
return data;};