1

import React, { useState, useEffect } from "react";
export default function Example() {
  const [count, setCount] = useState(0);
  const [tmp, setTmp] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
    setTmp(count);
    console.log(tmp);
  });
  return (
    <div>
      <p>
        You clicked {count} times and temp is {tmp}
      </p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}


After reading this I expected this to cause infinite re-render because a state tmp is getting changed inside the useEffect but it didn't, can someone please help what might be the cause?

cheems
  • 164
  • 7

1 Answers1

3

React setters ignore the set if the value didn't change. Repeatedly calling setTmp(0) will not trigger new renders. Change it to setTmp(n => n+1) and you will get the infinite loop you're looking for.

Slava Knyazev
  • 5,377
  • 1
  • 22
  • 43
  • 1
    But count is getting changed, isn't it? Hence, setTmp is getting new value every time. Am I missing something here? – cheems Jul 27 '23 at 14:38
  • 1
    @cheems Every render with an update `count` costs 2 renders instead of 1. The second render doesn't trigger a new one: https://codesandbox.io/s/sweet-chihiro-fy7ytk?file=/src/App.tsx – Slava Knyazev Jul 27 '23 at 18:13
  • Makes sense, but in the beginning why we have 2 times `Value not changed` instead of once? As per the link I mentioned it should runs first on mount and then on every re-render but no re-render occur until we click. – cheems Jul 27 '23 at 18:25
  • @cheems That is caused by Strict Mode (effects run twice). Remove it from index.ts and it will disappear. – Slava Knyazev Jul 27 '23 at 18:26
  • 1
    Thanks, you are the best! (シ_ _ )シ – cheems Jul 27 '23 at 18:35