【问题标题】:React.js export async functionReact.js 导出异步函数
【发布时间】:2021-01-11 17:41:55
【问题描述】:

我是 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);
        }
      })

【问题讨论】:

    标签: reactjs async-await weather-api


    【解决方案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}&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, state, country, setGeolocation);
           }catch(e){
               console.error(e);
           }
       })();
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 谢谢比拉尔,它确实有帮助。
      • 如果我的回答对你有帮助,请给我点赞
      【解决方案3】:

      一旦将异步函数与 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
          
          }
      

      【讨论】:

      • 感谢您的回复。我尝试这样做导出,我收到此错误:'import' 和 'export' 可能只出现在顶层 (44:2)2)
      • 这不起作用,因为您已经在应用程序功能中
      • 哦,我的坏是懒惰注意,是的,不幸的是你需要将两者分开
      • 谢谢思南,没关系,您介意解释一下为什么它不起作用吗?我不明白为什么在 App.js 中导出它不起作用。
      • 因为是另一个函数内的函数,所以只有不在作用域内,即在顶层时,才能导出。
      猜你喜欢
      • 2019-10-28
      • 2021-03-21
      • 1970-01-01
      • 2017-11-25
      • 2018-03-24
      • 2019-01-15
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      相关资源
      最近更新 更多