Home > OS >  Why component in react only renders twice when I change the state from the button click
Why component in react only renders twice when I change the state from the button click

Time:12-10

I am learning react recently, I created a component in which i created three buttons "post", "user", "comment". When i click one of the buttons, the name of the button shows below the buttons and also logs the button name is console. I am confused as to why a button logs the name only twice in console if clicked consecutively, 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 user button is clicked twice consecutively it logs it's name twice but not more if clicked again, it should log in console only once. I think it is related to useState hook. Here is my code. Please help me understand this react behaviour.

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>
  )
}

CodePudding user response:

React components automatically re-render whenever there is a change in their state or props. in your case clicking the button, changes the state setResourceType('post') which causes a re-render and executes console.log(resourceType). but clicking it again will not change the state it is the same resourceType = 'post' so the component will not re-render and console.log(resourceType) will not be executed

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>
  )

CodePudding user response:

As @Armands Uiska alluded to in his comment, the answer is in the React docs (API Hooks Reference) buried 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".

  • Related