React doesn’t always trigger a re-render on setState

Pablo Garcia
2 min readOct 29, 2021

--

For new React developers, it is common to think that setState will trigger a re-render. But this is not always the case.

If the value doesn’t change, React will not trigger a re-render.

Let’s say we had the following custom React hook that returns the day of the month:

function useDayOfTheMonth() {
const [day, setDay] = useState(null);
useEffect(() => {
const intervalId = setInterval(() => {
console.log('inside the interval')
setDay(new Date().getDate());
}, 500);
return /*cleanup*/ () => clearInterval(intervalId)
}, [setDay]);
return day
}

This hook internally runs an interval every 500 milliseconds which is absolutely scary because inside we are always calling setDay.

In these cases, React doesn’t trigger a re-render because the state did not change. If the current day is 5, it will be the exact same value as long as the number is the same. Once it changes, React will immediately receive the update and trigger a re-render.

Either way, I recommend wrapping the setState call inside an if statement just to take control of when it actually renders. You could inadvertently be re-rendering because you assume the value didn’t change. So, doing the following is always safer:

const currentDay = new Date().getDate()
if(day !== currentDay) {
setDay(currentDay)
}

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

In the example below, you can clearly see in the console that the interval is logging every 500 milliseconds, but the logging at the component level only happens twice, because React is bailing out as the value doesn’t change.

--

--

Pablo Garcia
Pablo Garcia

Written by Pablo Garcia

Senior Engineer at Netflix, ex-Staff Architect 2 at PayPal. M.S. in Computer Science w/specialization in Computing Systems. B.Eng. in Computer Software.

No responses yet