根据API响应更新视图

时间:2019-03-19 19:47:48

标签: react-native

在子组件的App.js状态对象中显示信息时遇到问题。以下是相关部分。 App.jsWeatherDetail是上述组件,然后是API请求的响应。

App.js

import React from "react";
import openweather from "../api/openweather";
import SearchBar from "./SearchBar";
import WeatherDetail from "./WeatherDetail";

class App extends React.Component {
  state = { weather: [], daily: [] };

  onSearchSubmit = async zip => {
    const currentWeather = openweather.get("/data/2.5/weather", {
      params: { zip }
    });

    const fiveDayForecast = openweather.get("/data/2.5/forecast", {
      params: { zip }
    });

    const [weather, daily] = await Promise.all([
      currentWeather,
      fiveDayForecast
    ]);

    this.setState({ weather: weather.data, daily: daily.data.list });
  };

  render() {
    return (
      <div>
        <SearchBar onSubmit={this.onSearchSubmit} />
        <WeatherDetail weather={this.state.weather} />
      </div>
    );
  }
}

export default App;

WeatherDetail.js

const WeatherDetail = ({ weather }) => {
  return (
    <div>
      <h1>Today</h1>
      <h3>City: {weather.name}</h3>
      <h5>Temperature:</h5>
    </div>
  );
};
>forecast:
   base: "stations"
  >clouds: {all: 75}
   cod: 200
  >coord: {lon: -82.54, lat: 40.7}
   dt: 1553023267
   id: 420031370
  >main:
     humidity: 45
     pressure: 1030
     temp: 44.22
     temp_max: 46.99
     temp_min: 41
   name: "Elyria"

现在,weather.name毫无问题地显示在视图中。如果我尝试获取比该信息更深的信息,则会收到一条错误消息,指出该属性未定义。例如,weather.main.temp是我认为可以获得温度的方式,但它显示出该错误。仅weather.main会给出一个明显的错误,但是它在消息中显示了我要访问的对象。因此,当weather.main.temp也说未定义属性(主)时,我会感到困惑。我是试图错误地访问该对象还是其他设置错误?

1 个答案:

答案 0 :(得分:0)

在您从API收到结果之前,问题在于初始渲染。 WeatherDetail第一次渲染时,它具有默认状态,您已将其设置为state = { weather: [], daily: [] };。这意味着在初始渲染时,main上不存在state.weather属性。它只是一个空数组。只有在运行onSearchSubmit时填充属性时,这些属性才会存在。

我会在您的WeatherDetail组件中添加一些验证。类似于以下内容:

const WeatherDetail = ({ weather }) => {
  const { name, main } = weather;
  return (
    <div>
      <h1>Today</h1>
      <h3>City: { name ? name : ''}</h3>
      <h5>Temperature: { main ? main.temp : '' }</h5>
    </div>
  );
};

这样,在初始呈现时,如果属性不存在,您仍然可以呈现空字符串,并且当填充状态并且存在正确的属性时,它将呈现正确的内容。