Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

196
Visualizações
Why use useMemo and not useCallback here?

So as i understand the difference between the two is that useCallback is used if a function or object or array is returned while useMemo when a primitive is returned. But i was looking up debouncing (this is the article: https://dmitripavlutin.com/react-throttle-debounce/ and it said useMemo would be a better solution. With useCallback

import { useState, useCallback } from 'react';
import debounce from 'lodash.debounce';
export function FilterList({ names }) {
  const [query, setQuery] = useState("");
  let filteredNames = names;
  if (query !== "") {
    filteredNames = names.filter((name) => {
      return name.toLowerCase().includes(query.toLowerCase());
    });
  }
  const changeHandler = event => {
    setQuery(event.target.value);
  };
  const debouncedChangeHandler = useCallback(
    debounce(changeHandler, 300)
  , []);
  return (
    <div>
      <input 
        onChange={debouncedChangeHandler} 
        type="text" 
        placeholder="Type a query..."
      />
      {filteredNames.map(name => <div key={name}>{name}</div>)}
    </div>
  );
}

With useMemo

import { useState, useMemo } from 'react';
import debounce from 'lodash.debounce';
export function FilterList({ names }) {
  const [query, setQuery] = useState("");
  let filteredNames = names;
  if (query !== "") {
    filteredNames = names.filter((name) => {
      return name.toLowerCase().includes(query.toLowerCase());
    });
  }
  const changeHandler = (event) => {
    setQuery(event.target.value);
  };
  const debouncedChangeHandler = useMemo(
    () => debounce(changeHandler, 300)
  , []);
  return (
    <div>
      <input
        onChange={debouncedChangeHandler}
        type="text"
        placeholder="Type a query..."
      />
      {filteredNames.map(name => <div key={name}>{name}</div>)}
    </div>
  );
}

And i don't understand. Is debounce returning a primitive value? If not how can we use useMemo? Also how is useMemo better than useCallback here?

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

First about your quote:

useCallback is used if a function or object or array is returned while useMemo when a primitive is returned

No, this is wrong. useCallback is mainly for memoizing functions. useMemo helps to avoid expensive calculations.


Now for the article. That article prefers useMemo for a different reason, that of performance; although I doubt in most such cases the performance difference will be noticeable.

 const debouncedChangeHandler = useCallback(
    debounce(changeHandler, 300)
  , []);

It says:

However... this implementation has a small performance issue: each time the component re-renders, a new instance of the debounced function is created by the debounce(changeHandler, 300).

It is saying that even though the debouncedChangeHandler remains the same across re renders due to useCallback, the debounce(changeHandler, 300) is still executed on each render.

But with useMemo:

  const debouncedChangeHandler = useMemo(
    () => debounce(changeHandler, 300)
  , []);

it claims:

useMemo(() => debounce(changeHandler, 300), []) memoizes the debounced handler, but also calls debounce() only during initial rendering of the component.

Because useMemo unlike useCallback doesn't directly call debounce, rather calls it inside an inline function.


Run this code:

let T1 = () => console.log('test1');
let T2 = () => console.log('test2');

export default function App() {
  let f = React.useCallback(T1(), []);
  let g = React.useMemo(() => T2(), []);
  let [x, setX] = React.useState(0);
  return (
    <div
      onClick={() => {
        setX(x + 1);
      }}
    >
      <h1>{x}</h1>
      <p>Start editing to see some magic happen :)</p>
    </div>
  );
}

Click div anywhere and see how test2 isn't logged anymore.

about 4 years ago · Juan Pablo Isaza Relatório

0

  const debouncedChangeHandler = useCallback(
    debounce(changeHandler, 300)
  , []);

in every render:

  1. debounce(changeHandler, 300) will run(it is not a function, it is a called function) and resolve into a value(which is a callback)
  2. then useCallback will run, check the the dependency to determine whether it should return memoized value(callback) or new value, so in your case, it will return memoized value
  const debouncedChangeHandler = useMemo(
    () => debounce(changeHandler, 300)
  , [])

in every render

  1. () => debounce(changeHandler, 300) will not run, it is value(callback)
  2. then useMemo will run, it will check the dependency to determine whether to run the callback or not, in your case, it will not run the callback

hence useMemo are more efficient

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda