Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

155
Vistas
Confused about the strange performance of useMemo Hook in React

This is my own hook which is used to realize debounce in React Hooks

import { useMemo, useRef } from "react";
import { debounce } from "lodash";

export function useDebounceFn(fn, wait) {
  const fnRef = useRef(fn)
  fnRef.current = () => {
    debugger
    fn()
  }

  const debounceFn = useMemo(() => {
    // Case One: can get the newest fn everytime
    return debounce(() => {
      fnRef.current()
    });

    // Case Two: only can get the first fn
    return debounce(fnRef.current);
  }, []);

  return {
    run: debounceFn,
    cancel: debounceFn.cancel,
  }
}

I think debounce(fnRef.current) is equal to debounce(() => { fnRef.current() }) ,but the truth is that they are different and i wonder why. Is there any wrong with my code or just useMemo do something different in these two cases.

  const { run } = useDebounceFn(() => {
    console.log("num", num);
  });

  useEffect(() => {
    run();
  }, [num]);

When i use case one, i can get the newest num and this is what i want to realize, but when i use case two, everytime run function only can get the inital num. i want to know why the case two only can get the inital value, in others word, why the case one can always get the newest value in useMemo.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I think debounce(fnRef.current) is equal to debounce(() => { fnRef.current() }), but the truth is that they are different and I wonder why.

  • Case 1 returns a memoized function that calls a function that gets the current ref value and invokes it. When the returned run function is invoked, the current ref value is "unpacked".
  • Case 2 closes over the initial ref value in the decorated debounced function. It will never be updated for the life of the component.

You could fix case 2 by populating the useMemo hook's dependency array to re-enclose the current ref value.

Example:

export function useDebounceFn(fn, wait) {
  const fnRef = useRef(fn);

  const debounceFn = useMemo(() => {
    // Re-"cache" the function
    fnRef.current = () => {
      debugger
      fn()
    }

    // Re-decorate with debounce HOF
    return debounce(fnRef.current);
  }, [fn]);

  return {
    run: debounceFn,
    cancel: debounceFn.cancel,
  }
}

BTW, for case 1 you should use an useEffect hook to set the ref value when the fn updates.

Example:

export function useDebounceFn(fn, wait) {
  const fnRef = useRef(fn);

  useEffect(() => {
    fnRef.current = () => {
      debugger
      fn();
    }
  }, [fn]);

  const debounceFn = useMemo(() => {
    return debounce(() => {
      fnRef.current();
    });
  }, []);

  return {
    run: debounceFn,
    cancel: debounceFn.cancel,
  }
}
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda