3

I have been learning react recently, and I created a component in which I have created three buttons: "post", "user", and "comment". When I click one of the buttons, the name of the button shows below the buttons and also logs the button's name, which is console. I am confused as to why a button logs the name only twice in console if clicked consecutively, since from my understanding it should log only once. I tried removing <React.StrictMode> from the index.js file but still it only logs twice. Example: if the user button is clicked twice consecutively, it logs its name twice but not more if clicked again, it should log into the console only once. I think it is related to the useState hook. Please help me understand this react behaviour. Here is my code:

export default function Hello() {

const [resourceType, setResourceType] = useState('post')

console.log(resourceType)

return (
  <div>
      <button onClick={() => setResourceType('post')}>Post</button>
      <button onClick={() => setResourceType('user')}>User</button>
      <button onClick={() => setResourceType('comment')}>Comments</button>
      <h1>{resourceType}</h1>
  </div>
  )
}
Steve
  • 11,596
  • 7
  • 39
  • 53
  • This will probably give you the idea. https://stackoverflow.com/questions/61254372/my-react-component-is-rendering-twice-because-of-strict-mode – dogukyilmaz Dec 09 '22 at 18:17
  • I removed the strict mode but still i dont think it is related to strict mode. – Prashant Singh Dec 09 '22 at 18:25
  • I think here you can find answer: https://stackoverflow.com/questions/57652176/react-hooks-usestate-setvalue-still-rerender-one-more-time-when-value-is-equal – Armands Uiska Dec 09 '22 at 20:21

3 Answers3

4

The value is logged twice on two consecutive clicks of the same button, and then not on subsequent consecutive clicks, because of the State hook's bailout. As @Armands alluded to in his comment, the answer is in the React docs (API Hooks Reference) referenced in this post which states:

Bailing out of a state update
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects.

Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree. If you’re doing expensive calculations while rendering, you can optimize them with useMemo.

So if your case, since the console.log(...) is in the component body, it's still being fired before React "bails out".

Steve
  • 11,596
  • 7
  • 39
  • 53
2

React components automatically re-render whenever there is a change in their state or props. in your case clicking the button the first time, changes the state setResourceType('post') which causes a re-render and executes console.log(resourceType). but clicking it the second time will not change the state it is the same resourceType = 'post' in this phase React may still need to re-render that specific component again and console.log(resourceType) will be executed. then it stops rerendering in spite of clicking the button .

Note : onClick is an Event handler only re-run when you perform the same interaction again (clicking the button )

change your component like this if you want to log resourceType to the console every time you click the button :

 const [resourceType, setResourceType] = useState('post') 
  
return (
  <div>
      <button onClick={ ()=>{ setResourceType('post'); console.log( resourceType)} }>Post</button>
      <button onClick={() =>{ setResourceType('user'); console.log( resourceType)}}>User</button>
      <button onClick={() => {setResourceType('comment'); console.log( resourceType)}}>Comments</button>
      <h1>{resourceType}</h1>
  </div>
  )
monim
  • 3,641
  • 2
  • 10
  • 25
-1

The reason can be found in the react documentation React docs (API Hooks Reference)

Bailing out of a state update If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects.

Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree. If you’re doing expensive calculations while rendering, you can optimize them with useMemo.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 14 '22 at 13:47