0

经过一系列代码试用后,我无法将 API 中的 JSON 文件存储到状态中

在完全实现之前,我一直在尝试在浏览器控制台控制台上显示 JSON 响应。我有这个代码:

//const API;
class WeatherApp extends React.Component{
    constructor(props){
        super(props);


        this.state = {
            location: "",
            reports:[]
        }
    }

//functions should be written outside the constructor method
    onSubmit = event => {
        //prevents default loading of the page when this function "onSubmit"
        //is called
        event.preventDefault();
        //saving the value of the textbox to a variable/const
        if(this.searchbox.value !== ""){ 
            const searchResult = this.searchbox.value;
            //update the state object
            this.setState({
                location: searchResult + " weather report"
            });
        }else{
            alert("please ensure that field is not empty!");
            return;
        }
    };


//${this.searchbox.value + KEY}
componentDidMount(){
    if(this.searchbox.value !== ""){ 
        fetch(`api.openweathermap.org/data/2.5/forecast?q=${this.searchBox.value + KEY} `, {
            method: "GET",
            dataType: "JSON"
        })
        .then( data =>  
            this.setState({ reports: [...this.state.reports, data.list ], })
        );
    }
}


    render(){
        console.log(this.state.reports);

        return(
            <div className="weather-app">
                <WeatherAppHeader />
                <div className="weather-body">
                    <div className="entry-pane">
                        <form onSubmit ={this.onSubmit} >
                            <input 
                                type="text" 
                                id="search-box"
                                placeholder="Location e.g Abuja, NG" 
                                size="40" 
                                ref={input => this.searchbox = input} />

                            <button type="submit" id="search-btn">search</button> 
                        </form>
                    </div>
                    <SearchedLocation  location={this.state.location} />
                    <WeatherReport  reports={this.state.reports} />
                </div>
            </div>

        );
    }
}

但我没有返回包含 JSON 对象的响应,而是得到了这个响应。请问我该如何解决这个问题?

[ length: 0    __proto__: Array(0)]
4

2 回答 2

0

fetch获取 JSON 时,需要使用 .json 将响应对象解析为JSON

etch(`api.openweathermap.org/data/2.5/forecast?q=${this.searchBox.value + KEY} `, {
            method: "GET",
            dataType: "JSON"
        })
        // ..  ....
        .then(response => response.json())
        .then( data =>  
            this.setState({ reports: [...this.state.reports, data.list ], })
        );

查看MDN 上fetch使用的一些示例。https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetchresponse.json()

于 2019-08-03T00:35:59.420 回答
0

在这个特定的组件中,您实际上并没有提出请求。你只会这样做,didMount除非它总是空的,所以 fetch 永远不会执行。您应该清理此组件的工作方式。

class WeatherApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      location: "",
      reports: []
    };
  }

  //functions should be written outside the constructor method
  onSubmit = event => {
    //prevents default loading of the page when this function "onSubmit"
    //is called
    event.preventDefault();
    //saving the value of the textbox to a variable/const
    if (this.searchbox.value.trim() === "") {
      alert("please ensure that field is not empty!");
      return;
    }
    const searchQuery = this.searchbox.value;
    //update the state object
    this.setState({
      location: searchQuery + " weather report"
    });
    this.searchForReport(searchQuery); 
  };

  searchForReport = searchQuery => {
    fetch(
      `api.openweathermap.org/data/2.5/forecast?q=${searchQuery}&APPID=${KEY}`,
      {
        method: "GET",
        headers: { "Content-Type": "application/json" }
      }
    )
    .then(response => {
      if (!response.ok) {
        // TODO handle bad request here
      }
      response.json();
    })
    .then(data => {
      const report = data ? data.list : [];
      this.setState({ reports: [...this.state.reports, report] });
    });
  };

  render() {
    ...
  }
}

这一点是当您提交表单时,您需要实际获取数据。因此,您希望在验证输入后执行此操作。我可能会将您输入的值放在组件上并以这种方式引用它而不是引用。

将您的变量更新KEY为只是 api 键,并将其作为参数传递。使您的代码易于理解和可读。如果下一个开发人员必须去查找一个变量以了解代码是如何工作的,那么这是一个不应该存在的依赖项。

于 2019-08-03T01:33:38.263 回答