【问题标题】:Function after async Function [closed]异步功能后的功能[关闭]
【发布时间】:2021-12-18 07:39:57
【问题描述】:

我是 React 的新手,我正在尝试制作天气网站。我想先获取访问者的IP,然后获取城市位置,然后直接通过Openweather获取天气情况。这是我的代码,希望有人能帮我解答如何完成这个网站,谢谢

import { useState, useEffect } from "react";
import axios from "axios";
require("dotenv").config();

function IpGet() {
  const [ip, setIP] = useState("");
  const [countryName, setcountryName] = useState("");
  const [cityName, setcityName] = useState("");
  const [countryCode, setcountryCode] = useState("");
  const [countryStateName, setcountryStateName] = useState("");

  const WeatherKey = process.env.REACT_APP_WEATHERKEY;

  const getData = async () => {
    const res = await axios.get("https://geolocation-db.com/json/");
    setIP(res.data.IPv4);
    setcountryName(res.data.country_name);
    setcityName(res.data.city);
    setcountryCode(res.data.country_code);
    setcountryStateName(res.data.state);
  };

  // const getWeather = async () => {
  //   const WeatherUrl = await axios.get(
  //     `https://api.openweathermap.org/data/2.5/weather?q=${cityName},${countryStateName}&appid=${WeatherKey}`
  //   );
  // };

  useEffect(() => {
    getData();
  }, []);

  return (
    <div className="IpGet">
      <h4>{ip}</h4>
      <h4>{countryName}</h4>
      <h4>{countryCode}</h4>
      <h4>{countryStateName}</h4>
      <h4>{cityName}</h4>
    </div>
  );
}

export default IpGet;

【问题讨论】:

  • 你能说得更清楚一点吗?
  • 如果你想从openweather中获取基于城市的数据,你需要使用第二个useEffect调用和[cityName]作为它的依赖数组。这样当cityName 发生变化时,里面的函数就会运行。

标签: javascript reactjs api


【解决方案1】:

这个问题很模糊,但这里有点猜测。

开始的一些提示:

  • 对于大多数前端解决方案,您可能不需要 axios。这只是一个额外的依赖。请改用fetch API
  • 保持变量名称一致 - setCountryName 而不是 setcountryName
  • useMemo 挂钩将阻止在每次渲染时创建函数。您可以传递包含变量的依赖数组的第二个参数。如果其中任何变量发生变化,useMemo 将重新计算该函数。

现在看代码。您可以给useEffect 变量数组的第二个参数。如果这些变量中的任何一个发生变化,效果将运行作为第一个参数提供的回调函数。 useEffect 也会在组件挂载时运行一次。

创建第二个效果,当您获得调用天气 API 所需的数据时运行。

考虑到以上所有因素,您的代码现在可能看起来像这样(未经测试):

import { useState, useEffect } from 'react';
require('dotenv').config();

function IpGet() {
    const [ip, setIP] = useState('');
    const [countryName, setCountryName] = useState('');
    const [cityName, setCityName] = useState('');
    const [countryCode, setCountryCode] = useState('');
    const [countryStateName, setCountryStateName] = useState('');

    const weatherKey = process.env.REACT_APP_WEATHERKEY;

    // useMemo to avoid recreating this function on every render
    const getData = React.useMemo(() => async () => {
        const res = await fetch('https://geolocation-db.com/json/');
        setIP(res.data.IPv4);
        setCountryName(res.data.country_name);
        setCityName(res.data.city);
        setCountryCode(res.data.country_code);
        setCountryStateName(res.data.state);
    });

    const getWeather = React.useMemo(() => async () => {
        if (!cityName || !countryStateName || !weatherKey) return;

        const weatherUrl = `https://api.openweathermap.org/data/2.5/weather?q=${cityName},${countryStateName}&appid=${weatherKey}`;
        const weatherData = await fetch(weatherUrl);

        // Do something with weatherData here... set to some state or something.
    });

    useEffect(() => {
        getData();
    }); // No dependency array, so this will only run once when the component mounts

    useEffect(() => {
        getWeather();
    }, [cityName, countryStateName]); // This will trigger the callback when any of these variables change.

    return (
        <div className='IpGet'>
            <h4>{ip}</h4>
            <h4>{countryName}</h4>
            <h4>{countryCode}</h4>
            <h4>{countryStateName}</h4>
            <h4>{cityName}</h4>
        </div>
    );
}

export default IpGet;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-04
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多