Home > Mobile >  React: When does not the count value changes in setInterval?
React: When does not the count value changes in setInterval?

Time:12-10

I know this code will work and the count value will be updated after every 2 seconds:

import React from 'react';

function App() {
  const [count, setCount] = React.useState(0);

   React.useEffect(() => {
     setInterval(() => {
       setCount(prev => prev   1);
     }, 2000);
   }, []);

  return <h1>{count}</h1>;
}

I am trying to understand why the below code doesn't work:

React.useEffect(() => {
    const interval = setInterval(() => {
      setCount(count   1);
      console.log('hello');
    }, 2000);

    return () => clearInterval(interval);
  }, []);

In this case, count stays at 1 but the setInterval is called after every 2 seconds because hello is being logged every 2 seconds.

  1. How setInterval is being called when component is not being rendered? Does it operate outside of React lifecycle or something?

  2. When I pass callback to setCount(prev => prev 1), then it works fine? Why? How the prev in callback getting the updated value?

I have read similar answers but still it is not making sense to me so if someone could please clear the doubt.

Thanks

CodePudding user response:

How setInterval is being called when component is not being rendered? Does it operate outside of React lifecycle or something?

Yes, setInterval is a function that's part of the core javascript language. By calling setInterval, you ask the browser to call the specified function every 2000ms. React is not involved in this.

When I pass callback to setCount(prev => prev 1), then it works fine? Why? How the prev in callback getting the updated value?

The useState hook is designed to allow this interaction. React promises that if you pass a function into setCount, then react will call your function and pass in the latest value.

The exact code with which they implement this can be tricky to step through since they reuse a lot of general purpose functions to implement several different hooks, but if you want to poke around their codebase you can look here: https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.new.js#L1525

CodePudding user response:

When you create the interval function, count will be the value at the moment of creation (so 0). When it gets called later, it will still hold that value, since it won't get changed in that context. So it will always set it to 0 1, so 1.

When you pass a callback function, it will use the current, correct value.

Hope this could clear things up!

CodePudding user response:

This version: setCount(prev => prev 1) uses the previous state value every-time the interval gets run.

This version: setCount(count 1) uses count when the useEffect was las run (in this case 0, so 0 1). Because there is an empty dependency array this hook is only run once.

If count was included in the dependency array of useEffect then it would get re-run when the value of count changes.

Running this may help to see what's going on:

  React.useEffect(() => {
    console.log('running useEffect')
    const interval = setInterval(() => {
      setCount(count   1);
      console.log('hello ', count);
    }, 500);

    return () => {
      console.log('clear interval')
      clearInterval(interval);
    }
  }, [count]);
  • Related