в то время как цикл не работает в крючке useEffect

#react-native #while-loop #react-hooks #settimeout #use-effect

Вопрос:

Я хочу получать местоположение устройства каждые 7 секунд, устанавливая состояние с текущими значениями местоположения. Я делаю цикл while в крючке useEffect и использую setTimeot для ожидания 7 секунд. Но пока цикл никогда не выполняется. Что не так с этим подходом и как я могу решить проблему?

 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()

}, [])
 

Ответ №1:

Я не уверен на 100%, почему whuile(true) это не работает … Но почему бы вам не использовать «брата setTimeout»? 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);
  };
}, []);
 

Комментарии:

1. Работало именно так, как я хотел. Спасибо.

Ответ №2:

Вот как это можно было бы сделать с помощью setTimeout .

В следующей статье объясняются некоторые тонкости выбора одного из них по сравнению с другим.

TLDR setTimeout обычно является лучшим выбором

Повторяющиеся события: Тайм-аут или интервал?

 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);
  };
}, []);