Avoiding Unnecessary Renders with useMemo

Conveniently, useMemo also lets you skip an expensive re-render of a child. Clicking "change a" logs a new Child render since 'a' is a dependency of the memoized element. Clicking "change b" does not re-render Child at all: 'child' still holds the very same memoized element reference as before, and React skips re-rendering a subtree when the element it receives is reference-identical to last time.
RESETRUNFULL
<!DOCTYPE html><html><head>
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  </head><body>
    <div></div>
    <script type="text/babel">
      function Child({ a }) {
        console.log('Child rendered, a='+a);
        return <p>Child sees a = {a}</p>;
      }
      function Parent({ a, b }) {
        const child = React.useMemo(() => <Child a={a} />, [a]);
        return (
          <React.Fragment>
            {child}
            <p>Parent sees b = {b}</p>
          </React.Fragment>
        );
      }
      function Example(){
        const [a, setA] = React.useState(0);
        const [b, setB] = React.useState(0);
        return (
          <React.Fragment>
            <button onClick={()=>setA(a+1)}>change a</button>
            <button onClick={()=>setB(b+1)}>change b</button>
            <Parent a={a} b={b}/>
          </React.Fragment>
        );
      }
      const root = ReactDOM.createRoot(document.querySelector("div"));
      root.render(<Example/>);
    </script>
  </body></html>

You may rely on useMemo as a performance optimization, not as a semantic guarantee. It only serves as a hint, and doesn't guarantee the computation won't re-run.