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

101
Vistas
How React.memo works with useCallback

As far as I understand, React.memo is an API that memoize a component: if its props don't change, react use the latest render of that component without comparing it with its previous version. Skipping this comparing speed-up the app. Cool.

Now, here's what I don't get: if props don't change, also a not memoized component don't get re-rendered, as I can see from that simple code: there's no difference about number of renders between a normal component+usecallback and a memoized one+useCallback. Basically, useCallbacks is all I need, as a normal component doesn't get re-rendered with same props. Then, what I'm I missing? When memo comes in help to optimize?

import { useCallback, useEffect, useState, memo, useRef } from "react";
import "./styles.css";

function Child({ fn, txt }) {
  const [state, setState] = useState(0);
  console.log(txt + " rendered!");

  useEffect(() => {
    setState((state) => state + 1);
  }, [fn]);

  return (
    <div style={{ border: "solid" }}>
      I'm a Child
      {!fn && <div>And I got no prop</div>}
      {fn && <div>And I got a fn as a prop</div>}
      <div>and I've got rendered {state} times</div>
    </div>
  );
}

const MemoChild = memo(({ fn, txt }) => {
  const [state, setState] = useState(0);
  const counter = useRef(0);
  console.log(txt + " rendered!", counter.current);

  useEffect(() => {
    setState((state) => state + 1);
    counter.current++;
  }, [fn]);

  return (
    <div style={{ border: "solid" }}>
      I'm a Child
      {!fn && <div>And I got no prop</div>}
      {fn && <div>And I got a fn as a prop</div>}
      <div>and I've got rendered {state} times</div>
    </div>
  );
});

export default function App() {
  const [, setState] = useState(true);

  const handlerOfWhoKnows = () => {};

  return (
    <div className="App">
      I'm the parent
      <br />
      <button onClick={() => setState((state) => !state)}>
        Change parent state
      </button>
      <h3>Ref</h3>
      ref: <Child txt="ref" fn={handlerOfWhoKnows} />
      <h3>useCallback test</h3>
      useCB: <Child txt="useCb" fn={useCallback(handlerOfWhoKnows, [])} />
      memo: <Child txt="memo" fn={handlerOfWhoKnows} />
      memo + useCB:{" "}
      <MemoChild txt="memo+useCb" fn={useCallback(handlerOfWhoKnows, [])} />
    </div>
  );
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Your example is misleading you a bit because you never change the state of App.

Now, here's what I don't get: if props don't change, also a not memoized component don't get re-rendered...

That's incorrect. If the parent re-renders, an unmemoized child will re-render, even if its props don't change.

When memo comes in help to optimize?

When you don't want that to happen. :-)

Here's an example, notice that Unmemoized re-renders as the counter goes up , but Memoized does not; neither of them uses the counter, so neither of them needs to re-render, but the unmemoized one does anyway because that's the default behavior:

const { useState, useEffect } = React;

const Unmemoized = ({ value }) => {
    console.log(`Unmemoized rendering with "${value}"`);
    return <div>Unmemoized: {value}</div>;
};

const Memoized = React.memo(({ value }) => {
    console.log(`Memoized rendering with "${value}"`);
    return <div>Memoized: {value}</div>;
});

const Example = () => {
    const [counter, setCounter] = useState(0);

    useEffect(() => {
        const timer = setInterval(() => {
            setCounter(c => {
                ++c;
                if (c === 5) {
                    clearInterval(timer);
                }
                return c;
            });
        }, 800);
        return () => {
            clearInterval(timer);
        };
    }, []);

    return (
        <div>
            <div>Counter: {counter}</div>
            <Memoized value="a" />
            <Unmemoized value="b" />
        </div>
    );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

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