简体   繁体   中英

while loop is not working in useEffect hook

I want to get device location in every 7 seconds set set the state with current location values. I am making a while loop in useEffect hook and use setTimeot to wait 7 seconds. But while loop never executes. What is wrong with this approach and how can i solve the problem?

const sleep = (milliseconds) => {
    setTimeout(() => { }, milliseconds)
}


const getPosition = () => {
    
        while (true) {
            GetLocation.getCurrentPosition({
                enableHighAccuracy: true,
                timeout: 15000,
            })
                .then(location => {
                    const { latitude, longitude, altitude, accuracy } = location
                    setPosition({ lat: latitude, lon: longitude, alt: altitude, acc: accuracy })
                    alert("latitude: " + latitude + "\nlongitude: " + longitude)
                    setLoading(false)
                })
                .catch(err => alert(err))
            sleep(7000)
        }
          
}


useEffect(() => {
    getPosition()

}, [])

I'm not 100% sur why the whuile(true) doesn't work ... But why don't you use the "setTimeout's brother" setInterval :

const getPosition = () => {
  GetLocation.getCurrentPosition({
    enableHighAccuracy: true,
    timeout: 15000,
  })
    .then((location) => {
      const { latitude, longitude, altitude, accuracy } = location;
      setPosition({
        lat: latitude,
        lon: longitude,
        alt: altitude,
        acc: accuracy,
      });
      alert('latitude: ' + latitude + '\nlongitude: ' + longitude);
      setLoading(false);
    })
    .catch((err) => alert(err));
};

useEffect(() => {
  const intervalID = setInterval(getPosition, 7*1000);

  // Don't forget to clear the interval when unmounting the component :
  return () => {
    clearInterval(intervalID);
  };
}, []);

Here is how it would be done using setTimeout .

The following article explains some subtleties of choosing one over the other.

TLDR setTimeout is usually a better choice

Repeated Events: Timeout or Interval?

const loopInterval = 7*1000;
let loop;

const getPosition = () => {
  GetLocation.getCurrentPosition({
    enableHighAccuracy: true,
    timeout: 15000,
  })
  .then((location) => {
    const { latitude, longitude, altitude, accuracy } = location;
    setPosition({
      lat: latitude,
      lon: longitude,
      alt: altitude,
      acc: accuracy,
    });
    alert('latitude: ' + latitude + '\nlongitude: ' + longitude);
    setLoading(false);
    loop = setTimeout(getPosition, loopInterval);
  })
  .catch((err) => alert(err));
};

useEffect(() => {
  loop = setTimeout(getPosition, loopInterval);
  // Clear the timeout when unmounting the component :
  return () => {
    clearTimeout(loop);
  };
}, []);

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