Hypothesis
Hypothesis

Reputation: 1389

Why IF statement causes a loop

I have a simple piece of code like this :

ReactDOM.render(<Change />, document.getElementById('app'));

function Change() {
    const [i, setI] = React.useState(0);
    let rnd = 9;
    if (i !== rnd) {
        setTimeout(() => {
            setI(i + 1);
        }, 500);
    }
    React.useMemo(() => {
        console.log(i);
    }, [i]);
    return (
        <div>
            <h1>I change the state</h1>
        </div>
    );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

<div id="app"></div>

I don't understand why if (i !== rnd) Initiates a loop as the condition should just check the condition one time and move on with the code.

My thought process is like this :

  1. i is 0 and is not equal 9 so it goes into the time out and waits for 500 ms

  2. runs the increment and i becomes 1

  3. console.log should show 1 being printed

  4. end

Why does it become a loop and check whether i is equal to rnd or not as many as the i is not equal rnd ?

Upvotes: 0

Views: 81

Answers (3)

Elan Hamburger
Elan Hamburger

Reputation: 2177

React works on a system of re-renders. When you change a variable that is used in your UI, Javascript doesn't know directly that you've changed it. That's why you have to use a state variable (useState) with a setter function and can't just declare a variable like you would in a backend setting. When something in the UI changes, React rerenders the entire component, so it effectively calls your function again.

When you use the state setter function setI, you are telling React to

  1. Change the value of i AND
  2. Rerender using the new value

So, stepping through your code here:

  1. Initial render: i = 0 and rnd = 9
  2. i !== rnd is true since 0 !== 9, the timeout is set
  3. The component renders
  4. The timeout expires, i = i + 1, rerender
  5. Second render: i = 1 and rnd = 9
  6. i !== rnd is true since 1 !== 9, the timeout is set
  7. ...

So it's not that your if is causing a loop, it's that your function is being called multiple times.

Upvotes: 1

Alex V
Alex V

Reputation: 216

You're setting state in the setTimeout callback which triggers a re-render, which essentially is calling your Change function again with an incremented value of i. In that call the timeout gets set again, and then the state gets updated again which causes another re-render, and it goes on and on until i becomes equal 9.

Upvotes: 2

Nathan
Nathan

Reputation: 499

It looks like you're calling setI which will update the state and in turn re-render the component & the if condition?

Upvotes: 2

Related Questions