为什么在函数返回之前未在此处调用React的useEffect挂钩?

时间:2020-11-03 23:20:15

标签: reactjs asynchronous promise axios use-effect

下面的useEffect钩子应该设置weather变量,但它没有这样做-相反,React组件会在调用该钩子之前返回。

为什么在React组件返回之前没有调用useEffect钩子,我该如何解决此问题?

// A React component that shows a given city's weather.
const CityWeather = ({ city }) => {
  const [weather, setWeather] = useState({})
 
  useEffect(() => {
    axios
      .get(`http://api.weatherapi.com/v1/current.json` +
        `?key=${process.env.REACT_APP_MY_SUPER_SECRET_WEATHER_API_KEY}` +
        `&q=${city}`)
      .then(response => {
        console.log(`response is ${JSON.stringify(response)}`)
        setWeather(response.data)})
  },
  [city])

  console.log(`The value of the weather var is ${JSON.stringify(weather)}`)
  return (
    <div>
      <h1>Weather in {city}</h2>
      <p>temperature: {weather.current.temp_c} Celsius</p>
      <img src={weather.current.condition.icon} alt="weather forecast"/>
      <p>wind speed: {weather.current.wind_mph} mph</p>
      <p>wind dir.: {weather.current.wind_dir}</p>
    </div>
  )
}

1 个答案:

答案 0 :(得分:1)

这是因为对api的调用是异步的,这意味着代码将在后台进行提取的同时继续执行,当返回响应时,它将在代码的.then()部分进行回调效果。

一种常见的做法是在加载数据时显示一个占位符:

const CityWeather = ({ city }) => {
  const [weather, setWeather] = useState(null);

  useEffect(() => {
    axios
      .get(
        `http://api.weatherapi.com/v1/current.json` +
          `?key=${process.env.REACT_APP_MY_SUPER_SECRET_WEATHER_API_KEY}` +
          `&q=${city}`,
      )
      .then((response) => {
        console.log(`response is ${JSON.stringify(response)}`);
        setWeather(response.data);
      });
  }, [city]);

  console.log(`The value of the weather var is ${JSON.stringify(weather)}`);
  return (
    <div>
      {!weather ? (
        <h3>Loading the weather!</h3>
      ) : (
        <>
          <h2>Weather in {city}</h2>
          <p>temperature: {weather.current.temp_c} Celsius</p>
          <img src={weather.current.condition.icon} alt="weather forecast" />
          <p>wind speed: {weather.current.wind_mph} mph</p>
          <p>wind dir.: {weather.current.wind_dir}</p>
        </>
      )}
    </div>
  );
};

(此外,我注意到您将weather默认设置为数组([]),这可能会导致其他问题)