0

For comparison purpose I wrote same logic as class vs. function component, and noticed some behavioral differences.

Class component with bind:

this.logName = this.logName.bind(this);

then function component with useCallback:

const logName = useCallback(() => {
   console.log(`Name is - ${state.name}`);
}, [state.name]);

Inside these, I'm calling child component (wrapped in react.memo for performance):

import React, { useEffect, useState } from "react";

const ChildComp = (props) => {
  const [state, setState] = useState(0);
  useEffect(() => {
    console.log("child render");
    setState((state) => state + 1);
  }, [props]);
  return (
    <div className="child">
      <h4>Child Comp ({state})</h4>
      <button onClick={props.log}>Log Name </button>
    </div>
  );
};

//export default ChildComp;
export default React.memo(ChildComp, (p, n) => p.log === n.log);

Sandbox here

If I update age, due to react.memo it doesn't re-render child, it's expected and working fine in both, but if I update state.name in functional, child re-render (due to dependency in useCallback), but doesn't in class. Due to bind in class component I always get right value, but can't remove dependency ([state.name]) in functional, else I will get old value.

Please help me understand this. Do I need to optimize function component more to get same behavior as class (no child rendering even state.name update), and how can I do so?

7
  • Does this answer your question? Why can't `useCallback` always return the same ref Commented Oct 24, 2023 at 20:46
  • @EmileBergeron I feel its different than what Joseph asked in that question. My questions is more about do we really need that much optimization for performance and if yes, how I can get exact same behavior as class component. Commented Oct 24, 2023 at 20:55
  • Classes and functions are different constructs, so naturally, each comes with its own caveats. There's a common misconception with React that a re-render is always bad, but it's only the case if the output changes (or side-effects re-run on render). React will render a child component, see that it doesn't trigger any changes and will bail out, not rendering the entire tree and not changing the DOM. In your example though, you're preventing this optimization by setting the state on each render through a dependency on the whole props object. Commented Oct 24, 2023 at 21:10
  • However, callbacks are a common source of issues with React function components with things such as stale state being captured in callbacks and the different ways to solve it properly. Commented Oct 24, 2023 at 21:15
  • @EmileBergeron thanks for explanation and my understand is also the same. FYI, tried without setState and useEffect also using useRef. eg - const count = useRef(0); count.current = count.current + 1; then also child re-render in functional component Commented Oct 24, 2023 at 21:42

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.