1

The function does not run again as the state remains the same as it should in the first case.

Works as expected, I have no issues with it.

import {useState, useEffect} from 'react'

export default function App(){
  const [name, setName] = useState("Joe")
  
  console.log("render")

  return (
    <div>
      <h1>{name}</h1>
      <button onClick={()=>{setName("Joe")}}>
        Change Name
      </button>
    </div>
  )
}

In the first case, the output after pressing the Change Name button: first code render nothing happened. You can just see the first render text, there is no second but in the second case the situation is slightly different.

import {useState, useEffect} from 'react'

export default function App(){
  const [name, setName] = useState("Joe")
  
  console.log("render")

  return (
    <div>
      <h1>{name}</h1>
      <button onClick={()=>{setName("Jane")}}>
        Change Name
      </button>
    </div>
  )
}

After the first render i press the button and the state changes to Jane and the component is rendered again as it should. second code second render

but after that when i press the button again component should not be called again because state has not changed. However, the component is called again and rendering takes place again.

enter image description here

After that, when I press the button again, the component is not called again and does not work as it should.

My question is: Why component is called again even though the state is the same? Why did it work differently in the second case, although in the first case it was not called again when the state was the same?

I tried to debug etc. and couldn't find anything helpful.

Thanks for all answers.

2 Answers2

0

It depends on the type of value you are setting inside setState

  • If your state is a primitive i.e number, string, booleanthen setting the same value using setState hook won't trigger a rerender as it uses Pass By Value.

  • If your state is an Object or Array then it will rerender because of Pass By Reference.

Note: The strange behavior of rerendering twice though same primitive object is passed is still a mystery !!! May be it is related to react's internal implementation specifics.

Futher Reference: Set state with same value using hooks will cause a rerender?

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
  • Then can you explain why it is not rendering again in the first case? Thank you. – Semih Aksoy Dec 28 '22 at 02:22
  • For the second situation, when I pressed the button after the third render, why didn't it render again? Thank you. – Semih Aksoy Dec 28 '22 at 02:25
  • I have made my research and finally tried my best to give you the explanation. 2 time rendering is still a mystery :| . Refer the reference link for more insight to the problem – krishnaacharyaa Dec 28 '22 at 08:21
0

NOTE: OP notes that React Strict Mode is not in play

Famous point about React: "State in React is a snapshot". That is described in detail at this link.

Queuing is described here

Essentially, one extra render is required for the next snapshot to synchronize with the state change once the Object.is test is true. Once the state is synchronized, it will remain so.

  • initial state (triggers render) -- render logged
  • initial state === new state (triggers render of new snapshot) -- render logged
  • new state === new state (triggers render of new snapshot) -- render logged

State machine is now up to date and there will be no further renders until the state changes again. The console with only show render once for each change from this point forward.

This is demonstrated in the StackBlitz below. Run the app, click on each button in turn. You will see render logged in the console. Finally, click on any button twice in a row - you will see the extra render logged. Any subsequent clicks on that button will not produce render in the console.

Demo

Randy Casburn
  • 13,840
  • 1
  • 16
  • 31