Why setState causes too many rerender Error even though the state hasn't changed

Viewed 455

Hi I'm learning React now and having trouble with the state..

I know when the state changes, the component re-renders and the code in UseEffect widout depth only runs once. But I can't explain exactly why infinite rendering occurs when I write setState in JSX or in the render syntax.

below code causes infinite re-render

import React, { useState, useEffect } from 'react'

const index = () => {
  const [active, setActive] = useState(false);
  console.log("render", active);
  setActive(false);
  
  return (
    <div>
      
    </div>
  )
}

export default index

But the code below has no problem even though it keeps calling setState.

import React, { useState, useEffect } from 'react'

const index = () => {
  const [active, setActive] = useState(false);
  console.log("render", active);

  useEffect(() => {
    setInterval(()=>{
      console.log("run")
      setActive(true)
    },0);
  }, [])
  
  return (
    <div>
      
    </div>
  )
}

Does setState trigger re-rendering regardless of state value? I want to know the exact reason why using setState outside of useEffect causes an error.

2 Answers

This is happening because, in the first case, when useEffect is not used, you are updating your state right after declaring it. Even if you are setting the state as false again, but for react, the state has been updated. And the first rule of thumb for react is, if state update happens, component will re render.

This is why you are getting an infinite rerendering.

your code is following the below flow:

  1. Declare state variable and pass value as false
  2. Update state to false
  3. State updated, hence component re rendered.
  4. Step 1 again.

In second case, where use effect is used, your state will update only when the component is mounted, which means, after that any state update won't trigger your useEffect.

Based on React documentation: https://reactjs.org/docs/hooks-reference.html#usestate

The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.

And there is an addition: https://reactjs.org/docs/hooks-reference.html#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. (React uses the Object.is comparison algorithm.) Note that React may still need to render that specific component again before bailing out.

And here is the important part: React may still need to render that specific component again before bailing out.

So yes, the component may still rerender even if the values are the same.

Related