1

I have a seemingly elementary problem that keeps setting my projects back--useState isn't rendering correctly for me.

Here is a simplified version of the issue:

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

  function TestFunction() {
    for (let i = 0; i < 10; i++) {
      setCount((curr) => curr + 1);
      console.log(count);
    }
  }

  return (
    <>
      <h3>Count = {count}</h3>
      <button onClick={() => TestFunction()}>Click</button>
    </>
  );
}

export default App;

Upon clicking the button, the state is then set to 10, but the console.log() isn't properly updated.

Any help is appreciated.

Thanks

-S

sevisin
  • 13
  • 2

2 Answers2

1

I hope this answers your question

First of all you are logging count which is not yet updated for the current render. So basically console.log is one step behind. Check the code bellow this might clarify everything to you.


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

function TestFunction() {
 for (let i = 0; i < 10; i++) {
   setCount((curr) => {
     console.log(curr);
     return curr + 1;
   });
   console.log(count);
 }
}

return (
 <>
   <h3>Count = {count}</h3>
   <button onClick={() => TestFunction()}>Click</button>
 </>
);
}

export default Temp;```


Sulman Azhar
  • 977
  • 1
  • 9
  • 26
0

You are logging count before it is updated with the latest value. Simply put, when setCount is called, React stores the value provided to it until the next render. When the next render occurs the count value will be updated.

In my example below:

  • The useEffect below will be hit every time state is updated.
  • The setState(curr=>curr+1) will notify you what the current ~next~ state value is.

const {
  useState,
  useEffect
} = React;

function App() {
  const [state, setState] = useState(0);

  // Console.log on state update
  useEffect(()=>{
    console.log(`useEffect: ${state}`);
  },[state]);


  function TestFunction() {
    for(let i = 0; i < 10; i++) {
      setState((curr)=>{
        console.log(`setState(nextValue): ${curr+1}`);
        return curr+1;
      });
    }
  }

  return (
    <div>
      <h3>Count = {state}</h3>
      <button onClick={TestFunction}>Click</button>
    </div>
  );
}

const el = document.querySelector("#root");
ReactDOM.render(<App/>, el);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

<div id="root"></div>

Hope that clarifies things.

Miroslav Glamuzina
  • 4,472
  • 2
  • 19
  • 33