0

In this case I'm sending same props and state for Child component, so... why has not re-render without React.memo() and those logs show just once?

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const Child = ({ num }) => {
  const [count, setCount] = useState(0);

  return (
    <>
      {console.log('Child rendered')}
      {count}<br />
      {num}<br />
      <button onClick={() => setCount(count)}>Add</button>
    </>
  )
}

const App = () => {
  const [num, setNum] = useState(0);

  return (
    <>
      {console.log('App rendered')}
      <Child num={num} />
      <button onClick={() => setNum(num)}>Add</button>
    </>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
Martin Rützy
  • 415
  • 1
  • 11
  • 22
  • @Quentin I don't think the the duplicate mark is really correct. There are subtle differences. It's not such a big deal, because I believe the question should be closed regardless as a 'Not reproducible or was caused by a typo', but I find the duplicate a bit misleadiing, especially if I were the OP – Samuel Hulla Nov 04 '20 at 08:44

2 Answers2

0

You're not changing any values

() => setNum(num)

is the same as

() => setNum(0)

which is the same as initital state (0), hence no re-render occurs

Samuel Hulla
  • 6,617
  • 7
  • 36
  • 70
0

The child component doesn't rerender because the state reference to num never changes. It is always set to the same reference. react uses shallow reference equality to reconcile state and prop updates.

const App = () => {
  const [num, setNum] = useState(0);

  return (
    <>
      {console.log('App rendered')}
      <Child num={num} />
      <button onClick={() => setNum(num)}>Add</button> // <-- same object reference
    </>
  )
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181