Diferencia Entre useState() y useMemo() en React JS

Entender las diferencias entre dos hooks fundamentales de React: useState() y useMemo(), es esencial para mejorar el rendimiento de tu aplicación.

  Nota

El hook useState() se utiliza para almacenar y actualizar datos que pueden cambiar con el tiempo, mientras que useMemo() se utiliza para memorizar y reutilizar valores calculados. Aunque ambos son hooks, tienen propósitos completamente diferentes.

¿Qué es el hook useState() en React JS?

useState() es un hook que te permite agregar y manejar estado en componentes funcionales. El estado es información que puede cambiar con el tiempo y cuando cambia, React vuelve a renderizar el componente.

  ¿Cuándo usar useState()?

  • Cuando necesitas almacenar datos que pueden cambiar
  • Para manejar inputs de formularios
  • Para controlar si algo está visible u oculto
  • Para contar clicks, likes, etc.

Sintaxis Básica

A continuación, se muestra la sintaxis básica de useState():

jsx
const [variable, setVariable] = useState(valorInicial);

Significa que estás creando una variable con estado en React.

  Importante

  • variable: guarda el valor actual del estado.
  • setVariable: es la función para cambiar ese valor.
  • useState(valorInicial): define el valor inicial del estado.

Cada vez que se actualiza la variable de estado, React vuelve a renderizar el componente y se actualiza el valor en la interfaz de usuario.

Ejemplo Práctico

jsx
import { useState } from 'react'; // Importamos useState de React

function Contador() {
// Creamos una variable de estado llamada "count" con valor inicial 0
const [count, setCount] = useState(0);

return (
      <>
          <p>Has clickeado {count} veces</p>
          <button onClick={() => setCount(prevCount => prevCount + 1)}>
              Incrementar
          </button>
      </>
  );
}
export default Contador;
  ¿Qué pasa aquí?

  1. count guarda el número de clicks
  2. setCount es la función para actualizar ese número
  3. Cada vez que hacemos click, el componente se vuelve a renderizar con el nuevo valor

¿Qué es el hook useMemo() en React JS?

useMemo() es un hook que memoriza el resultado de un cálculo costoso y lo reutiliza en lugar de recalcularlo en cada render. Es como guardar el resultado de una operación compleja para no tener que hacerla de nuevo.

  ¿Cuándo usar useMemo()?

  • Cuando tienes cálculos pesados o complejos
  • Para filtrar o procesar listas grandes
  • Cuando quieres evitar cálculos innecesarios
  • Para optimizar el rendimiento

Sintaxis Básica

A continuación, se muestra la sintaxis básica de useMemo():

jsx
const resultado = useMemo(() => {
  // cálculo costoso aquí
  return valorCalculado;
}, [dependencias]);

Significa que useMemo() guarda el resultado de un cálculo para no volver a hacerlo cada vez que el componente se renderiza.

  Importante

La función dentro de useMemo(() => { ... }) hace el cálculo. El array [dependencias] indica cuándo volver a recalcular (solo si cambian esas variables).

Ejemplo Práctico

jsx
// Importamos useState y useMemo de React
import { useState, useMemo } from 'react'; 

// Componente que filtra productos basados en la búsqueda
function ListaFiltrada() {
const [busqueda, setBusqueda] = useState(''); // Estado para la búsqueda

// Lista grande de productos
const productos = [
  'Laptop', 'Mouse', 'Teclado', 'Monitor', 'Auriculares',
  'Webcam', 'Micrófono', 'Mousepad', 'USB', 'HDMI'
];

// useMemo memoriza el filtrado
const productosFiltrados = useMemo(() => {
  console.log('Filtrando productos...');

  // Retorna los productos que contienen la búsqueda
  return productos.filter(p => 
    p.toLowerCase().includes(busqueda.toLowerCase()) // Filtrar productos que contienen la búsqueda
  );
}, [busqueda]); // Solo recalcula cuando cambia "busqueda"

return (
      <>
          <input
              type="text"
              value={busqueda}
              onChange={(e) => setBusqueda(e.target.value)}
              placeholder="Buscar producto..."
          />
          <ul>
              {
              productosFiltrados.map((producto, i) => (
                  <li key={i}>{producto}</li>
              ))}
          </ul>
      </>
);
}
  ¿Qué pasa aquí?

  1. El filtrado solo se ejecuta cuando busqueda cambia
  2. Si el componente se renderiza por otra razón, usa el resultado memorizado
  3. Ahorra procesamiento innecesario

Diferencias Clave

Propósito

  Propósito

  • useState: Maneja valores que cambian con la interacción del usuario.
  • useMemo: Evita recalcular cosas pesadas innecesariamente, mejorando el rendimiento.

Qué retorna

  Qué retorna

  • useState: Devuelve un array con [valor, funciónParaActualizarlo].
  • useMemo: Devuelve directamente el resultado del cálculo memorizado.

Re-render

  Re-render

  • useState: Provoca un nuevo render cuando el estado cambia.
  • useMemo: No causa render directamente, solo guarda el resultado.

Cuándo usar

  Cuándo usar

  • useState: Cuando el usuario interactúa (ej: contador, formularios, toggles).
  • useMemo: Cuando hay cálculos complejos (ej: filtros, ordenamientos, operaciones pesadas).

💡 Ejemplos

En el siguiente ejemplo se logra ver como useState guarda el estado del contador, mientras que useMemo guarda el resultado del cálculo del doble del contador.

jsx
// useState: contador simple
const [count, setCount] = useState(0);

// useMemo: cálculo optimizado
const doble = useMemo(() => count * 2, [count]);

Ejemplo Completo Comparativo

Otro ejemplo para ver la diferencia entre useState y useMemo es el siguiente:

jsx
import { useState, useMemo } from 'react';

function EjemploCompleto() {
// useState: para manejar el estado
const [numero, setNumero] = useState(5);
const [color, setColor] = useState('blue');

// useMemo: para optimizar cálculo factorial
const factorial = useMemo(() => {
  console.log('Calculando factorial...');
  let resultado = 1;
  for (let i = 1; i <= numero; i++) {
    resultado *= i;
  }
  return resultado;
}, [numero]); // Solo recalcula si "numero" cambia

return (
  <div>
    <h2>Cálculo de Factorial</h2>
    
    {/* useState en acción */}
    <input
      type="number"
      value={numero}
      onChange={(e) => setNumero(Number(e.target.value))}
    />
    
    {/* useMemo muestra el resultado memorizado */}
    <p>Factorial de {numero} = {factorial}</p>
    
    {/* Cambiar color NO recalcula el factorial */}
    <button onClick={() => setColor(color === 'blue' ? 'red' : 'blue')}>
      Cambiar Color
    </button>
    <div style={{ width: '100px', height: '100px', backgroundColor: color }} />
  </div>
);
}
  Observa que:

  • Cambiar numero recalcula el factorial ✅
  • Cambiar color NO recalcula el factorial ✅ (usa el valor memorizado)
  • Sin useMemo, el factorial se calcularía en cada render, lo cual es innecesario.

Errores Comunes


1Error con useState

Nunca modifiques la variable del estado directamente (count = ...), porque React no detectará el cambio y no volverá a renderizar el componente.
Siempre usa la función que te da useState (en este caso setCount) para actualizar el valor correctamente.

jsx
// INCORRECTO: modificar el estado directamente
count = count + 1; // ❌

// CORRECTO: usar la función setter
setCount(count + 1); // ✅

2Error con useMemo

Si olvidas agregar las dependencias correctas (como valor), useMemo no se actualizará cuando esas cambien, y el resultado quedará desactualizado.
Asegúrate de incluir todas las variables usadas dentro del cálculo en el array de dependencias.

jsx
// INCORRECTO: olvidar las dependencias
const resultado = useMemo(() => calcular(valor), []); // ❌

// CORRECTO: incluir todas las dependencias
const resultado = useMemo(() => calcular(valor), [valor]); // ✅