ReactJS: не удается получить API

avatar
pedrofromperu
9 августа 2021 в 03:03
40
1
2

Эй, я пытаюсь получить API, но он ничего не возвращает.

Я проверил и не могу получить доступ к предварительно созданным значениям внутри выборки.

Как я могу получить доступ к своим значениям внутри выборки?

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

function App() {
  const [ positionLat, setPositionLat ] = useState('') ;
  const [ positionLong, setPositionLong] = useState('') ;
  
  navigator.geolocation.getCurrentPosition(function(position) {
    setPositionLat(position.coords.latitude);
    setPositionLong(position.coords.longitude);
  });

console.log(positionLat) // returns good result
console.log(positionLong) // returns good result

// I obviously need to call those values inside my fetch

useEffect(() => {
  console.log(positionLat) // returns undefined
  console.log(positionLong) // returns undefined
  fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${positionLat}&lon=${positionLong}&appid={api_key}b&units=metric`)
   .then(res => {
    return res.json();
   })
   .then(data => {
    console.log(data)
   })
}, []);

  return (
    <div className="App">
      <p>lattitude :{positionLat}</p>
      <p>longitude :{positionLong}</p>
    </div>
  );
}

export default App;
Источник

Ответы (1)

avatar
CertainPerformance
9 августа 2021 в 03:06
4

Одним из вариантов является изменение хука эффекта, чтобы он запускал основную часть только после определения значений:

useEffect(() => {
  if (positionLat === '' || positionLong === '') {
    return;
  }
  // rest of function
  fetch(...
}, [positionLat, positionLong]);

Вам также необходимо исправить вызов геолокации, чтобы он выполнялся только один раз при подключении.

useEffect(() => {
  navigator.geolocation.getCurrentPosition(function(position) {
    setPositionLat(position.coords.latitude);
    setPositionLong(position.coords.longitude);
  });
}, []);

Еще один вариант — разделить его на два компонента и отображать дочерний компонент (который выполняет выборку) только после завершения вызова геолокации, что может выглядеть чище.

const App = () => {
    const [coords, setCoords] = useState();
    useEffect(() => {
        navigator.geolocation.getCurrentPosition(function (position) {
            setCoords(position.coords);
        });
    }, []);
    return coords && <Child {...coords} />;
};
const Child = ({ latitude, longitude }) => {
    useEffect(() => {
        fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid={api_key}b&units=metric`)
            .then(res => res.json())
            .then(data => {
                // do stuff with data
            })
            // .catch(handleErrors); // don't forget to catch errors
    }, []);
    return (
        <div className="App">
            <p>latitude :{latitude}</p>
            <p>longitude :{longitude}</p>
        </div>
    );
};