React.js 导出异步函数

问题描述

我是 React.js 的新手,所以请耐心等待。

我用 react.js 构建了一个天气 API 应用程序并且它工作正常。我不能做的一件事是导出我的 async function fetchData(e),这样我就可以从 App.js 范围之外的任何组件访问它。 如何导出异步 fetchData 以便它被驻留在 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}&limit=5&appid=${API_KEY}`;
    await fetch(geolocation_api_request_url)
      .then(function (res) {
        return res.json();
      })
      .then(function (data) {
        if (city && state && 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}&lon=${geolocation.lon}&exclude=minutely,hourly&appid=${API_KEY}&units=metric`;
          return fetch(weather_api_url);
        }
      })

解决方法

尝试按照以下方式进行。

-- 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}&limit=5&appid=${API_KEY}`;
        try{
            res = await fetch(geolocation_api_request_url);
            if(city && state && country){
                //set the latitude and longitude of the location
                const data = res.json();
                setGeolocation && 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}&lon=${geolocation.lon}&exclude=minutely,hourly&appid=${API_KEY}&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,setGeolocation);
       }catch(e){
           console.error(e);
       }
   })();
}
,

您可以将异步函数从 App 函数中分离出来:

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
    
    }
,

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

看看这个react js的上下文Api,通过使用这个,你可以在你的应用程序的任何组件中获得这个函数,你也可以更新它的值。