functional component with React.useCallback and React.memo() is re-rendering

Viewed 144

I was understanding the concepts of React. I wanted to try out few things.

Some of them are:

When parent state changes, does every functional child component re-renders, even if it doesn't have any props.

Seems like yes, this is my parent code:

function App() {


const [count, setCount] = React.useState(0);

  return (
    <div className="App">
      <AnimalX />
      <h1
        onClick={() => {
          setCount(count + 1);
        }}
      >
        InCrease Count {count}
      </h1>
    </div>
  );
}

export default App;

My AnimalX component:

export const AnimalX = React.memo(() => {
  return <div>{console.log("in render")}jhgh</div>;
});

When I was clicking on the H1 tag, my child component was rendering. To fix this I used React.memo() which prevented the re-render.

Now, I went ahead and started exploring useCallback. I read it about it that it caches the function b.w. different renders. So I changed my parent component and passed a prop like this:

function App() {
  const [count, setCount] = React.useState(0);

  const testFunction = React.useCallback(() => {
    console.log("testFunction");
  });

  return (
    <div className="App">
      <AnimalX show={testFunction} />
      <h1
        onClick={() => {
          setCount(count + 1);
        }}
      >
        InCrease Count {count}
      </h1>
    </div>
  );

Now, my assumption was that my AnimalX component will only render once, because I've used React.memo Inside it, and I am passing cached version of function. But that's not the case.

My Child Component was re-rendering with every click. Which made me shocked. And I am not able to figure out the reason.

If anyone can point me in right direction then it would be highly appreicated.

1 Answers

You missed the API, you should get an eslint warning too, missing a dependency array as second argument:

//                                                    v Deps array
const testFunction = React.useCallback(() => { ... }, []);

Refer to useCallback API at React docs.

Related