useEffect依赖于另一个useEffect,即使使用依赖项数组,该useEffect也会多次执行。为什么?

时间:2020-07-22 09:33:09

标签: javascript reactjs api asynchronous use-effect

我正在使用两个useEffects。

  1. 在第一个useEffect上,我将状态和纬度设置为空,并且状态为空。
   useEffect(() => { 
         navigator.geolocation.getCurrentPosition(geo => {
           setLat(geo.coords.latitude); 
           setLng(geo.coords.longitude);
         }); 
       }, []);
  1. 在第二个useEffect上,我在外部API中传递纬度和经度以获取所需的数据。
   useEffect(()=>{
    fetch(`https://someapi&lat=${lat}&lon=${lng}&format=json`)
      .then(res => console.log(res.json()))
      .then(data => setData(data))
      .catch(error => console.log("error", error));
    },[lat,lng])

在这里我第二次使用API​​的useEffect会执行一次以上(尽管我在依赖项数组中提到了lat,lng)。 问题是我每秒只能发出一个API请求。

我该如何克服?

1 个答案:

答案 0 :(得分:0)

正如@AdrianoRepetti在评论中所提到的,效果运行两次:在第一次渲染和lat / lng状态更改时。

可能的解决方案可能是存储坐标的先前状态和当前状态,并仅在发生更改时获取。这是代码示例:

function YourComponent() {
  // store both current and previous states
  const [latLng, setLatLng] = useState({ lat: 0, lng: 0 });
  const [prevLatLng, setPrevLatLng] = useState({ lat: 0, lng: 0 });

  useEffect(() => {
    navigator.geolocation.getCurrentPosition((geo) => {
      // set current
      setLatLng({
        lat: geo.coords.latitude,
        lng: geo.coords.longitude,
      });
    });
  }, []);

  useEffect(() => {
    // compare prev and current and fetch only if there was a change
    if (latLng.lat !== prevLatLng.lat || latLng.lng !== prevLatLng.lng) {
      fetch(`https://someapi&lat=${latLng.lat}&lon=${latLng.lng}&format=json`)
        .then((res) => console.log(res.json()))
        .then((data) => {
           // set prev as current
           setPrevLatLng(latLng);
           setData(data);
        })
        .catch((error) => console.log("error", error));
    }
  }, [latLng, prevLatLng]);

  return <div>...</div>;
}