skip to Main Content
const sum = useMemo(() => a + b, [a, b])

what will happen when a and b are interchanged. Like if a = 5, b = 10 in the current render. What will happen when a = 10, b = 5? will it re-render after it is changed?

Not getting the consistent answer for this.

3

Answers


  1. A re-render occurs whenever the state changes (among other things).

    In your case, the value of sum will be recomputed if either a or b changes. However, it won’t trigger a re-render of the component because it is not part of its state.

    Changing the value of a or b will provoke a re-render because they are either part of the state of the component or are passed as props.

    Login or Signup to reply.
  2. It’s not a matter of useMemo() hook, as it is created to cache result of intensive calculations.

    The question here, as noticed Florent, is what is a and b – are they props variables or state variables, or some other specific case.

    If it’s state or props – it will trigger re-render.

    If this is special case like value of uncontrolled input or saved using useRef(), it will not trigger re-render.

    Login or Signup to reply.
  3. You are confusing rendering for computing.

    Like if a = 5, b = 10 in the current render. What will happen when a = 10, b = 5? will it re-render after it is changed?

    No. The useMemo will never trigger a render.

    Having said that, the component will most likely re-render, because:

    • You changed the values of a and b by updating the state. Calling the setter will trigger a component render.

      // within your component
      setA(10); 
      setB(5);
      
    • You changed the values of a and b by mutating the component props. Changing props will also trigger a component render.

      // inside parent component render
      <YourComponent a={10} b={5} />
      

    So the change in a and/or b will already have triggered a render.


    Your question is probably if sum will recompute during the render. To which the answer is yes. If a and/or b changes value the useMemo function is executed and the new value is calculated.

    In your provided scenario sum is the result of a commutative operation. a + b produces the same result as b + a. However useMemo does not analyse the function passed and sees it as a black box. It does not know if the operation is commutative or not. Say you would have passed a - b instead, then swapping the a and b values produces a different value. Therefore useMemo has to recompute the result.

    An easy way to test this would be to add a console.log() inside the useMemo call.

    let counter = 0;
    
    function App() {
      const [a, setA] = React.useState( 5);
      const [b, setB] = React.useState(10);
      
      function swap() {
        setA(b);
        setB(a);
      }
      
      // const sum = React.useMemo(() => a + b, [a, b]);
      const sum = React.useMemo(() => {
        const result = a + b;
        console.log(`[${++counter}]`, "recomputing a + b =", result);
        return result;
      }, [a, b]);
      
      return (
        <div>
          <code>a = <input type="number" value={a} onChange={e => setA(+e.target.value)} /></code>
          <br />
          <code>b = <input type="number" value={b} onChange={e => setB(+e.target.value)} /></code>
          <br />
          <code>sum = {sum}</code>
          <br />
          <button type="button" onClick={swap}>swap</button>
        </div>
      );
    }
    
    ReactDOM.createRoot(document.querySelector("#root")).render(<App />);
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search