Ir al contenido
angel.library

usePrevious

usePrevious conserva el valor observado en el commit anterior sin solicitar un render adicional. Es útil para detectar una transición —por ejemplo, de saving a saved—, no para mantener una segunda copia del estado actual.

hooks/usePrevious.ts
import { useEffect, useRef } from "react"
export function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>(undefined)
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}

Durante render, ref.current todavía contiene el valor anterior. Después de que React confirma los cambios en el DOM, el efecto guarda el valor actual para el próximo render. Cambiar un ref no vuelve a renderizar el componente.

const previousStatus = usePrevious(status)
useEffect(() => {
if (previousStatus === "saving" && status === "saved") mostrarConfirmacion()
}, [previousStatus, status])

El primer render devuelve undefined. El ref se actualiza después del commit, por eso durante el siguiente render todavía contiene el valor anterior.

Este hook conserva un solo valor. Para deshacer acciones, auditoría o una secuencia completa necesitas un historial explícito, normalmente un reducer o almacenamiento externo. Tampoco sirve para ejecutar lógica “antes de cambiar”: React ya está renderizando el nuevo valor cuando el hook devuelve el anterior.

No lo uses para duplicar estado derivado. Si solo necesitas calcular algo desde el valor actual, hazlo durante render; usePrevious tiene sentido cuando importa la transición entre dos renders.

  • El undefined inicial debe formar parte del tipo y del caso de uso.
  • En Strict Mode de desarrollo pueden ocurrir renders adicionales; la lógica debe depender de commits, no de contar renders.
  • Si la comparación es costosa, decide primero si realmente necesitas conservar el objeto completo o una propiedad estable.
  • Para limpiar una suscripción anterior, usa directamente la función de cleanup del efecto; no necesitas usePrevious.