Bad ComponentDidMount函数进入我的95000每日通话 - ReactJS

时间:2018-06-05 19:13:29

标签: javascript reactjs api loops axios

我不确定我做错了什么......我正在使用FourSquare应用制作一个简单的应用。

  1. 用户输入一个位置,并通过this.state.places返回场地。
  2. 我循环浏览数据以获取我需要的所有场地信息。除了照片......我不得不向另一个FourSquare API写另一个axios请求,所以我可以得到该场地ID的照片...

    不知何故,我的ComponentDidMount函数已达到我的整个FourSquare报价限制。我是一个免费帐户 - 每天95,000个电话?我不确定这个函数有什么错误,导致它!

      componentDidMount() {
        axios.get('https://api.foursquare.com/v2/venues/explore?near=london&&client_id=MY_CLIENT_ID&client_secret=MY_CLIENT_SECRET&v=201806044&venuePhotos=1')
          .then((res) => {
            // RES VENUE DATA IS STORED IN PLACES
            this.setState(
              { places: res.data.response.groups[0].items.slice(0,12)});
    
            // LOOP THROUGH PLACES RES AND PULL OUT THE VENUE ID.
            for(var i = 0; i < this.state.places.length; i++) {
              const photosID = this.state.places[i].venue.id;
              console.log(this.state.places[i].venue.id);
    
              // NOW TAKE THE VENUE ID AND PLACE IT IN THIS SECOND API REQUEST
              return axios.get(`https://api.foursquare.com/v2/venues/${photosID}/photos?client_id=MY_CLIENT_ID&client_secret=MY_CLIENT_SECRET&v=20130815&ll=40.7,-74`);
            }
          })
          // THEN CONSOLE LOG THIS PHOTO RES DATA.
          .then((res) => {
            console.log('IDS RES:', res.data.response.photos.items[1]);
            // console.log('IDS RES:', res.data.response.photos.items[1].prefix.concat(res.data.response.photos.items[1].suffix));
          })
          .catch((err) => {
            console.log(err);
          });
      }
    

    基本上,这就是我想要做的事情:

    1. 来自第一个API的Axios请求。将状态传递到另一个组件并循环访问场地数据。
    2. 制作第二个axios API请求,从第一个API请求中取出VenueID并返回一个图像参考(来自第二个axios请求)......
    3. 此代码有什么问题?

      我也在控制台中收到此错误:

      xhr.js:178 GET https://api.foursquare.com/v2/venues/4ac518cef964a5201aa620e3/photos?client_id=JUTTZIYT3Y2ECNHCORRDKIPLW1FNSAH2PW0XRLJCMIPRKY1Q&client_secret=220HPNZNEX3I34URWK4SK33IJBA4UJM3PFSRJIFCYRJTGBBN&v=20130815&ll=40.7,-74 429 ()
      dispatchXhrRequest @ xhr.js:178
      xhrAdapter @ xhr.js:12
      dispatchRequest @ dispatchRequest.js:59
      Promise.then (async)
      request @ Axios.js:51
      Axios.(anonymous function) @ Axios.js:61
      wrap @ bind.js:9
      (anonymous) @ index.js:41
      Promise.then (async)
      componentDidMount @ index.js:32
      proxiedComponentDidMount @ createPrototypeProxy.js:66
      (anonymous) @ ReactCompositeComponent.js:262
      measureLifeCyclePerf @ ReactCompositeComponent.js:73
      (anonymous) @ ReactCompositeComponent.js:261
      notifyAll @ CallbackQueue.js:74
      close @ ReactReconcileTransaction.js:78
      closeAll @ Transaction.js:207
      perform @ Transaction.js:154
      batchedMountComponentIntoNode @ ReactMount.js:124
      perform @ Transaction.js:141
      batchedUpdates @ ReactDefaultBatchingStrategy.js:60
      batchedUpdates @ ReactUpdates.js:95
      _renderNewRootComponent @ ReactMount.js:317
      _renderSubtreeIntoContainer @ ReactMount.js:399
      render @ ReactMount.js:420
      (anonymous) @ app.js:44
      listener @ ready.js:23
      index.js:49 Error: Request failed with status code 429
          at createError (createError.js:16)
          at settle (settle.js:18)
          at XMLHttpRequest.handleLoad (xhr.js:77)
      

      完整代码

      import React from 'react';
      import axios from 'axios';
      
      import Header from '../components/header';
      import Navbar from '../components/Navbar';
      import Results from '../components/Results';
      
      import './index.css';
      
      class Layout extends React.Component {
      
        constructor() {
          super();
          console.log('CONSTRUCTOR');
      
          this.state = {
            places: [],
            searchData: '',
            photos: [],
            city: 'London'
          };
      
          this.handleChange = this.handleChange.bind(this);
          this.handleSubmit = this.handleSubmit.bind(this);
        }
      
        // COMPONENT WILL MOUNT
        componentWillMount() {
          console.log('COMPONENT WILL MOUNT');
        }
      
      
        //
        componentDidMount() {
          axios.get('https://api.foursquare.com/v2/venues/explore?near=london&&client_id={MYCLIENTID}&client_secret={MYCLIENT_SECRET}&venuePhotos=1')
            .then((res) => {
              // RES VENUE DATA IS STORED IN PLACES
              this.setState(
                { places: res.data.response.groups[0].items.slice(0,12)});
              console.log(res.data.response.groups[0].items.slice(0,12));
      
              // LOOP THROUGH PLACES RES AND PULL OUT THE VENUE ID.
              for(var i = 0; i < this.state.places.length; i++) {
                const photosID = this.state.places[i].venue.id;
                console.log(this.state.places[i].venue.id);
      
                // NOW TAKE THE VENUE ID AND PLACE IT IN THIS SECOND API REQUEST
                return axios.get(`https://api.foursquare.com/v2/venues/${photosID}/photos?client_id={MYCLIENT}&client_secret={MYCLIENT}&ll=40.7,-74`);
              }
            })
            // THEN CONSOLE LOG THIS PHOTO RES DATA.
            .then((res) => {
              console.log('IDS RES:', res.data.response.photos.items[1]);
              // console.log('IDS RES:', res.data.response.photos.items[1].prefix.concat(res.data.response.photos.items[1].suffix));
            })
            .catch((err) => {
              console.log(err);
            });
        }
      
        // MAKE AXIOS REQUEST/COMPONENT DID MOUNT
        // componentDidMount() {
        //   console.log('COMPONENT DID MOUNT');
        //
        //   axios.get('https://api.foursquare.com/v2/venues/explore?near=london&&client_id={MYCLIENT}&client_secret={MYCLIENT}&venuePhotos=1')
        //     .then(res => {
        //       // console.log('DATA', res.data.response.groups[0].items);
        //       this.setState(
        //         { places: res.data.response.groups[0].items.slice(0,12)});
        //       this.setState(
        //         { photos: res.data.response.groups[0].items.slice(0,12)});
        //     });
        // }
      
        // MAKE AXIOS REQUEST/COMPONENT DID MOUNT
        // componentDidMount() {
        //   console.log('COMPONENT DID MOUNT');
        //
        //   axios.get('https://api.foursquare.com/v2/venues/explore?near=london&&client_id={MYCLIENT}&client_secret={MYCLIENT}&v=201806044&venuePhotos=1')
        //     .then(res => {
        //       // console.log('DATA', res.data.response.groups[0].items);
        //       this.setState(
        //         { places: res.data.response.groups[0].items.slice(0,12)});
        //       this.setState(
        //         { photos: res.data.response.groups[0].items.slice(0,12)});
        //     });
        // }
      
        // LISTEN TO FORM ENTRY/HANDLE CHANGE
        handleChange(e) {
          this.setState({ searchData: e.target.value }, () => console.log(this.state.searchData));
        }
      
        // CHANGE RESULTS AND APPLY SEARCH TERM TO AXIOS REQUEST
        handleSubmit(e){
          e.preventDefault();
          console.log(this.state.searchData);
          this.setState({ city: this.state.searchData });
          axios.get(`https://api.foursquare.com/v2/venues/explore?near=${this.state.searchData}&client_id={MYCLIENT}&client_secret={MYCLIENT}`)
            .then(res => {
              this.setState({ places: res.data.response.groups[0].items.slice(0,12)});
              // console.log(res.data.response.groups[0].items);
            });
        }
      
      
        render() {
          return(
            <div className="animated fadeIn">
      
              <Navbar />
              <Header
                handleChange={this.handleChange}
                handleSubmit={this.handleSubmit}
              />
              <Results
                places={this.state.places}
                photos={this.state.photos}
                city={this.state.city}
              />
            </div>
          );
        }
      }
      
      
      export default Layout;
      
      export const query = graphql`
        query SiteTitleQuery {
          site {
            siteMetadata {
              title
            }
          }
        }
      `;
      

      ADDED JSX:

      import React from 'react';
      // import axios from 'axios';
      
      const Results = () => {
      
        // for(var i = 0; i < photos.length; i++) {
        //   const photosID = photos[i].venue.id;
        //   console.log(photos[i].venue.id);
        //
        //   axios.get(`https://api.foursquare.com/v2/venues/${photosID}/photos?client_id={MYCLIENTID}&client_secret={MYCLIENTSECRET}&v=20130815&ll=40.7,-74`)
        //     .then(res => {
        //       console.log('IDS RES:', res.data.response.photos.items[1]);
        //       // console.log('IDS RES:', res.data.response.photos.items[1].prefix.concat(res.data.response.photos.items[1].suffix));
        //     });
        // }
      
      
      
        return (
          <section>
            <h3 className="title has-text-centered">Top 9 Recommendations for {city}</h3>
              <div className="columns is-multiline">
                {places.map((place, i) => <div className="column is-one-third" key={i}>
                  <ul>
                    <li>
                      <div className="card-image box">
                        <figure className="">
                          <img className="image" src="https://s3-eu-west-1.amazonaws.com/video.gallereplay.com/artistarea/Restaurant%20at%20night_23376c1c-7d1e-4d6f-8efb-c581529540fb/Cinemagraph_plain/1280x720/cinemagraph.jpg"/>
                          <h4 className="has-text-left purple">{place.venue.name}</h4>
                          <h5 className="has-text-left has-text-grey">Category: {place.venue.categories[0].pluralName}</h5>
                          <h5 className="has-text-left has-text-grey">Why? {place.reasons.items[0].summary}</h5>
                          <h5 className="has-text-left has-text-link">Address: {place.venue.location.formattedAddress.slice(0,4)}</h5>
                          <h5 className="has-text-left has-text-link">ID: {place.venue.id}</h5>
                          {/* <img className="animated rotateIn" src={place.venue.categories[0].icon.prefix.concat(place.venue.categories[0].icon.suffix)}/> */}
                        </figure>
                      </div>
                    </li>
                  </ul>
                </div>)}
              </div>
      
          </section>
        );
      };
      
      export default Results;
      

2 个答案:

答案 0 :(得分:1)

我阅读了文档但在您的代码中找不到任何奇怪的内容,但是我发现您的网址使用的是在网站上指定的不同参数:https://developer.foursquare.com/docs/api/venues/photos


PARAMETERS

尝试更改:

https://api.foursquare.com/v2/venues/${photosID}/photos?client_id=MY_CLIENT_ID&client_secret=MY_CLIENT_SECRET&v=20130815&ll=40.7,-74`

https://api.foursquare.com/v2/venues/${photosID}/photos

答案 1 :(得分:1)

我认为我发现了问题,您在return循环中正在执行for。我稍微修改了代码并删除了状态逻辑,但您应该将其修改为您自己的代码。下面是一个关于如何在for循环中处理promise的示例。
注意:我没有对此进行测试,因此可能存在一些错误。

<强>代码

componentDidMount() {
   const exploreURL = 'https://api.foursquare.com/v2/venues/explore?near=london&&client_id=MY_CLIENT_ID&client_secret=MY_CLIENT_SECRET&v=201806044&venuePhotos=1';

   axios.get(exploreURL)
     .then(response => {
       //Store our fetch requests generated in the for loop
       var requests = [];
       // RES VENUE DATA IS STORED IN PLACES
       const places = response.data.response.groups[0].items.slice(0, 12);

       // LOOP THROUGH PLACES RES AND PULL OUT THE VENUE ID.
       for (var i = 0; i < places.length; i++) {
         const venueId = places[i].venue.id;
         console.log(venueId);

         // NOW TAKE THE VENUE ID AND PLACE IT IN THIS SECOND API REQUEST
         //Add request to all requests array
         requests.push(axios.get(`https://api.foursquare.com/v2/venues/${venueId}/photos`));
       }

        //This promise reolves when all requests have been resolved
        return Promise.all(requests);
     })
     // THEN CONSOLE LOG THIS PHOTO RES DATA.
     .then((res) => {
       console.log(res);
     })
     .catch((err) => {
       console.log(err);
     });
 }