React.js экспорт асинхронной функции

#reactjs #async-await #weather-api

#reactjs #асинхронный-ожидание #погода-api

Вопрос:

Я новичок в React.js , так что, пожалуйста, потерпите меня в этом вопросе.

Я создал приложение weather API с react.js и это работает. Единственное, что я не могу сделать async function fetchData(e) , это экспортировать мой файл таким образом, чтобы я мог получить к нему доступ из любого компонента, выходящего за рамки App.js . Как мне экспортировать асинхронные данные выборки, чтобы они распознавались всеми компонентами, которые находятся за пределами App.js ? Обратите внимание, что async function fetchData(e) для функции требуются все переменные, которые объявлены в начале App.js .

Я исключил свой ключ API из кода по понятным причинам, и я не включил весь код в функцию fetchData, потому что он очень длинный.

 function App() {
  //Variables
  const API_KEY = '';
  const METRE_SECOND_TO_KM_HR = 3.6;
  const DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  const options = {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  };

  const [weather, setWeather] = useState([]);
  const [geolocation, setGeolocation] = useState([]);

  async function fetchData(e) {
    //async function fetchData(e) {
    const city = e.target.elements.city.value;
    const state = e.target.elements.state.value;
    const country = e.target.elements.country.value;

    e.preventDefault();
    //fetch request with city, state and country - to get a latitude and longitude based on city name.
    const geolocation_api_request_url = `https://api.openweathermap.org/geo/1.0/direct?q=${city},${state},${country}amp;limit=5amp;appid=${API_KEY}`;
    await fetch(geolocation_api_request_url)
      .then(function (res) {
        return res.json();
      })
      .then(function (data) {
        if (city amp;amp; state amp;amp; country) {
          //set the latitude and longitude of the location
          setGeolocation({
            data: data,
            lat: data[0].lat,
            lon: data[0].lon,
          });
          //make a second fetch call, this time with latitude and longitude
          const weather_api_url = `https://api.openweathermap.org/data/2.5/onecall?lat=${geolocation.lat}amp;lon=${geolocation.lon}amp;exclude=minutely,hourlyamp;appid=${API_KEY}amp;units=metric`;
          return fetch(weather_api_url);
        }
      }) 

Ответ №1:

Попробуйте выполнить следующее.

— WeatherAPI.js —

 const fetchData = (city, state, country, setGeolocation) => {
    return new Promise(async(resolve, reject)=>{
        const geolocation_api_request_url = `https://api.openweathermap.org/geo/1.0/direct?q=${city},${state},${country}amp;limit=5amp;appid=${API_KEY}`;
        try{
            res = await fetch(geolocation_api_request_url);
            if(city amp;amp; state amp;amp; country){
                //set the latitude and longitude of the location
                const data = res.json();
                setGeolocation amp;amp; setGeolocation({
                    data: data,
                    lat: data[0].lat,
                    lon: data[0].lon,
                });
                
                //make a second fetch call, this time with latitude and longitude
                const weather_api_url = `https://api.openweathermap.org/data/2.5/onecall?lat=${geolocation.lat}amp;lon=${geolocation.lon}amp;exclude=minutely,hourlyamp;appid=${API_KEY}amp;units=metric`;
                resolve(await fetch(weather_api_url));
             }
         }catch(e){
             reject(e);
         }
    });
}
export fetchData;
 

— App.js —

 import {fetchData} from '../api/WeatherAPI";
...
function fetchDataFromGoogle(e) {
   ...
   (async()=>{
       try{
           const weatherData = await fetchData(city, state, country, setGeolocation);
       }catch(e){
           console.error(e);
       }
   })();
}
 

Ответ №2:

https://reactjs.org/docs/context.html#updating-context-from-a-nested-component

взгляните на этот контекстный Api react js, используя его, вы можете получить эту функцию в любом компоненте вашего приложения, а также обновить ее значения.

Ответ №3:

Вы можете экспортировать асинхронные функции как таковые, как только вы отделите их от функции приложения:

 export const fetchData = async (args) => {
// Your implementation

}
 

Что касается параметров, если все они являются константами, поместите их внутрь объекта json и передайте функции, поскольку экспортируемая функция не может получить доступ к этим переменным:

 const args = {
    API_KEY : '',
    METRE_SECOND_TO_KM_HR : 3.6,
    DAYS : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
    options : {
      weekday: 'long',
      year: 'numeric',
      month: 'long',
      day: 'numeric',
}
 

и передать этот объект функции в качестве параметра:

 export const fetchData = async (e, args) => {
    // Your implementation
    
    }
 

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

1. Спасибо за ваш ответ. Я попытался выполнить экспорт таким образом, я получаю эту ошибку: «импорт» и «экспорт» могут отображаться только на верхнем уровне (44: 2) 2)

2. это не может работать, потому что вы уже находитесь в функции приложения

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

4. Спасибо, Синан, все в порядке, не могли бы вы объяснить, почему это не сработает? Я не понимаю, почему не получилось бы экспортировать ее внутри App.js .

5. Поскольку это функция внутри другой функции, вы можете экспортировать только в том случае, если она не находится внутри области видимости, то есть когда она находится на верхнем уровне.