简体   繁体   English

反应-用用户输入进行API调用的正确方法是什么?

[英]React - What is the correct way to make an API call with user input?

I'm relatively new to React and am building a simple weather app to help me learn. 我是React的新手,正在构建一个简单的气象应用程序来帮助我学习。 I've read the docs extensively but I'm still stuck. 我已经广泛阅读了文档,但仍然遇到困难。 My app has user input where they can search for a city's weather forecast using the OpenWeatherMap API. 我的应用程序具有用户输入,他们可以在其中使用OpenWeatherMap API搜索城市的天气预报。 Currently, my component state looks like this: 目前,我的组件状态如下所示:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoaded: false,
      inputText: '',
      data: {
        dayOne: [],
        dayTwo: [],
        dayThree: [],
        dayFour: [],
        dayFive: [],
        daySix: []
      }
    };
  }
}

Once they click on the button to get the data, I use a handleSubmit() method with axios to fetch the data from the API. 他们单击按钮获取数据后,我将使用带有handleSubmit()方法从API中获取数据。 This successfully populates the component state. 这样可以成功填充组件状态。

For example, in the React Dev Tools I can see that I get the following data in this.state.data.dayOne[0] , which is exactly what I want: 例如,在React Dev Tools中,我可以看到我在this.state.data.dayOne[0]获得了以下数据:

0: {
  weather_data: {
    cityName: "London"
    date: "2019-08-05"
    description: "scattered clouds"
    temp: 21.79
    tempMax: 21.79
    tempMin: 21.41
    time: "18:00"
    weatherIcon: "03d"
  }
} 

Below my user input component, I have a panel component which displays the current weather data for that day. 在我的用户输入组件下方,我有一个面板组件,该面板组件显示当天的当前天气数据。 For clarity, I've reduced the size of the component here: 为了清楚起见,我在这里减小了组件的大小:

// In CurrentWeatherDisplay.js:

class CurrentWeatherDisplay extends Component {
  render() {
    return (
      <div className="col-12 border border-info">
        <div className="row">
          <div className="col-6 py-4">
            <p className="mb-0 h6">City name:</p>
          </div>
          <div className="col-6 py-4">
            <p className="mb-0 h6">{this.props.data.dayOne[0].weather_data.cityName}</p>
          </div>
        </div>
      </div>
    );
  }
}

The problem I have is that this.props.data.dayOne[0].weather_data.cityName does not exist until the API has been called, and so the app can't render. 我的问题是this.props.data.dayOne[0].weather_data.cityName在API被调用之前不存在,因此该应用程序无法呈现。 I've read the React docs and it says to use the componentDidMount() lifecycle method. 我已经阅读了React文档,并说要使用componentDidMount()生命周期方法。 But in their example, this is an API call that happens immediately - https://reactjs.org/docs/faq-ajax.html 但在他们的示例中,这是一个立即发生的API调用-https: //reactjs.org/docs/faq-ajax.html

My app is different because I update the state after the page has loaded, and only when the user has submitted the form . 我的应用程序与众不同,因为我仅在用户页面提交后才更新页面加载后的状态。 Any ideas how I can correct the structure of my app? 有什么想法可以纠正应用程序的结构吗?

It's fine if you want to put the code for loading into a callback function instead of componentDidMount. 如果您想将要加载的代码而不是componentDidMount放到回调函数中,那就很好。 The main thing you should take away from that article is to have a state value which starts off empty (or in some other way indicating that data has not been loaded), and a render function that knows what to render when it sees the state is empty. 您应该从该文章中摘取的主要内容是拥有一个开始为空的状态值(或以其他某种方式指示尚未加载数据),以及一个渲染函数,该函数知道看到状态时将渲染什么内容。空。

So for example, if you have a flag in your state called isLoaded, your render function can check if isLoaded is false, and when it see that it returns some placeholder. 因此,例如,如果您的状态中有一个名为isLoaded的标志,则渲染函数可以检查isLoaded是否为false,并在其看到返回某个占位符的情况下进行检查。

render() {
  if (!this.state.isLoaded) {
    return <div>Loading...</div>
  }

  // else, return the populated component
}

Then when you want to load data (componentDidMount in their example, handleSubmit in yours), do so and then call this.setState. 然后,当您要加载数据时(在其示例中为componentDidMount,在您的示例中为handleSubmit),请这样做,然后调用this.setState。 The new state will cause the component to rerender, and your render function now returns something different than before, using the new data. 新状态将导致组件重新呈现,并且您的呈现函数现在使用新数据返回的内容与以前有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM