开发者问题收集

无法读取未定义的属性“temp”

2021-06-20
2309

这是我第一次来这里。我刚刚开始学习 React,在创建天气应用时遇到了一点问题。当我尝试调用 temp 值时,我收到消息:无法读取未定义的属性“temp”。如果有人发现错误,我将非常感激您的提示。我附上了代码

import React, { useState } from "react";
import axios from "axios";
export default function Weather() {
  let [city, setCity] = useState("");
  let [weather, setWeather] = useState("");

  function showWeather(response) {
    setWeather(response.data);
  }
  function handleChange(event) {
    setCity(event.target.value);
  }
  function displayTemperature(event) {
    event.preventDefault();
    let url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=97a9745b0c3a1f932357060a2331ab49&units=metric`;
    axios.get(url).then(showWeather);
  }
  let form = (
    <div>
      <form onSubmit={displayTemperature}>
        <input type="text" onChange={handleChange} />
        <input type="submit" value="Search" />
      </form>
    </div>
  );
  return (
    <div>
      {form}
      <ul>
        <li>Temperature: {weather.main.temp}°C</li>
        <li>Description: {weather.weather[0].description}</li>
        <li>Humidity: {weather.main.humidity}%</li>
        <li>Wind: {weather.wind.speed}km/h</li>
        <li>
        <img
            src={`http://openweathermap.org/img/wn/${weather.weather[0].icon}@2x.png`}
            alt=""></img>
        </li>
      </ul>
    </div>
  );
}
2个回答

在初始状态下, weather 是一个空字符串,因此在 API 命中之前,您从 weather 访问的所有值都将不可用,因此您可以使用 可选链接

weather?.main?.humidity

或 && 运算符

weather && Array.isArray(weather) && weather[0].description

Codesandbox

import React, { useState } from "react";
import axios from "axios";
export default function Weather() {
  let [city, setCity] = useState("");
  let [weather, setWeather] = useState("");

  function showWeather(response) {
    setWeather(response.data);
  }
  function handleChange(event) {
    setCity(event.target.value);
  }
  function displayTemperature(event) {
    event.preventDefault();
    let url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=97a9745b0c3a1f932357060a2331ab49&units=metric`;
    console.log(url);
    axios.get(url).then(showWeather);
  }
  function getImageIcon(weather) {
    const value = weather && Array.isArray(weather) && weather[0].icon;
    return value;
  }
  let form = (
    <div>
      <form onSubmit={displayTemperature}>
        <input type="text" onChange={handleChange} />
        <input type="submit" value="Search" />
      </form>
    </div>
  );
  return (
    <div>
      {form}
      <ul>
        <li>Temperature: {weather?.main?.temp}°C</li>
        {weather && Array.isArray(weather) && weather[0]?.description}
        <li>
          Description:{" "}
          {weather && Array.isArray(weather) && weather[0].description}
        </li>
        <li>Humidity: {weather?.main?.humidity}%</li>
        <li>Wind: {weather?.wind?.speed}km/h</li>
        <li>
          <img
            src={`http://openweathermap.org/img/wn/${getImageIcon()}@2x.png`}
            alt=""
          ></img>
        </li>
      </ul>
    </div>
  );
}
DecPK
2021-06-20

显示错误是因为一开始 weather 的值是空字符串,而您正尝试从中访问属性 main.temp

您可以通过使用条件渲染来解决这个问题,即仅当 weather 不为空时才显示 list

同样与此问题无关,但您应该在获取数据进行错误处理时在 displayTemperature 方法中添加一个 catch 方法。

下面是一个例子:

import React, { useState } from "react";
import axios from "axios";

export default function Weather() {
  let [city, setCity] = useState("");
  let [weather, setWeather] = useState("");

  function showWeather(response) {
    setWeather(response.data);
  }
  function handleChange(event) {
    setCity(event.target.value);
  }
  function displayTemperature(event) {
    event.preventDefault();
    let url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=97a9745b0c3a1f932357060a2331ab49&units=metric`;
    axios.get(url)
      .then(showWeather)
      .catch(err => console.log(err));
  }
  let form = (
    <div>
      <form onSubmit={displayTemperature}>
        <input type="text" onChange={handleChange} />
        <input type="submit" value="Search" />
      </form>
    </div>
  );
  return (
    <div>
      {form}
      {/* Conditionally rendering the list */}
      {weather && (
        <ul>
          <li>Temperature: {weather.main.temp}°C</li>
          <li>Description: {weather.weather[0].description}</li>
          <li>Humidity: {weather.main.humidity}%</li>
          <li>Wind: {weather.wind.speed}km/h</li>
          <li>
            <img
              src={`http://openweathermap.org/img/wn/${weather.weather[0].icon}@2x.png`}
              alt=""></img>
          </li>
        </ul>
      )}
    </div>
  );
}
PR7
2021-06-20