简体   繁体   中英

setState not updating in useEffect

I have a simple component as follows:

import React, {useEffect, useState} from 'react';


function App() {

  const [bus1Points, setBus1Points] = useState();

  const updateBuses = () => {
    setTimeout(updateBuses, 1000);
    console.log(bus1Points);  // Undefined each second
  };

  setInterval(() => {
    console.log('Interval ' + bus1Points); // <-- Prints expected value
  }, 500)

  console.log(bus1Points);
  useEffect(() => {
    setBus1Points('TEST');
    updateBuses();
  }, []);

  return (
    <div style={{ height: '100%', width: '100%' }}>
      {bus1Points}
    </div>
  );
}

export default App;

I'm not sure why it's undefined each time. Is this a bug in React? Why would updateBuses only get the initial value of bus1points ? (Note that bus1points renders correctly in the UI)

it's undefined because state updates are reflected in the next render. When you see it correctly rendered in the UI, is because after your state update, ReactJs called another cycle of rendering (where bus1Points has the new value) and renders again the UI.

Whenever you do setBus1Points you're telling react to batch a new state value, but your variable bus1Points is just a value, so that's why it does not change

Update

the issue is that when you do

const updateBuses = () => {
    setTimeout(updateBuses, 1000);
    console.log(bus1Points);  // Undefined each second
  };

you're capturing the value of bus1Points (with a closure) in the first render. Given the initial value of bus1Points is undefined , you will always log that value. That's because updateBuses references a variable that's outside of its definition, so it "captures" that value, and it is called everytime through the recursive setTimeout .

Your setInterval , however, is being executed on every render, so you're capturing the new value of bus1Points (And you're also adding everytime more and more logs, generating a memory leak). This is not a recursive function so it captures in each render the new value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM