【问题标题】:React - Fetch multiple apisReact - 获取多个 api
【发布时间】:2019-02-08 07:52:08
【问题描述】:

我想同时从 2 个不同的 url 向多个 api 发出 get 请求,然后我只想用新属性“img”更新状态下的数组“items”,而不是覆盖它。我想在第一个请求中保留和属性。 这是我的尝试。

   componentDidMount(){

      let url = ``;
      let url2 = ``

        fetch(url,{
          method: 'GET'
        })
        .then((response)=> response.json())
        .then((responseJson) => {
          const newItems = responseJson.items.map(i => {
            return{
              itemId: i.itemId,
              name: i.name,
            };
          })
          const newState = Object.assign({}, this.state, {
            items: newItems
          });

          console.log(newState);
          this.setState(newState);
        })
        .catch((error) => {
          console.log(error)
        });
        fetch(url2,{
          method: 'GET'
        })
        .then((response)=> response.json())
        .then((responseJson) => {
          const newImg = responseJson.item.map( data=> {
            return{
              img: data.picture.url
            };
          })
          const newState = Object.assign({}, this.state, {
            items: newImg
          });

          console.log(newState);
          this.setState(newState);
        })
        .catch((error) => {
          console.log(error)
        });
    }

【问题讨论】:

    标签: reactjs rest api get fetch-api


    【解决方案1】:

    您绝对可以调用两个单独的 API。您遇到的问题是最后返回的 API 调用覆盖了从第一个 API 调用中保存的数据。这是解决此问题的代码。

    componentDidMount(){
    
      let api1 = `https://myapiexample1.com`;
      let api2 = `https://myapiexample2.com`;
    
      let promise1 = fetch(api1)
      .then(response => response.json())
      .then(json => json.items.map(item => {
        return {
          itemId: item.itemId
          name: item.name
        }
      }))
    
      let promise2 = fetch(api2)
      .then(response => response.json())
      .then(json => json.items.map(item => {
        return {
          img: item.img
        }
      }))
    
      Promise.all([promise1, promise2])
      .then(results => results[0].concat(results[1]))
      .then(items => this.setState({itmes}))
    }
    

    另一种不太干净但与您当前正在做的类似的方法是确保在向状态添加新项目时包含旧状态:

    this.setState({
      items: newItems.concat(this.state.items)
    })
    

    【讨论】:

    • 感谢您的回答,我尝试了您的解决方案,但您能查看我更新的问题吗?太令人沮丧了!
    • 我还是有点迷茫,你是想创建一个看起来像这样的items 对象:{{itemId: 123, name: test1}, {img: ...}} 还是像这样:{{itemId: 123, name: test1, img: ...}}
    • 像最后一个{{itemId: 123, name: test1, img: ...}}
    • 您的回答似乎是正确的,但它给了我这个错误,我不知道为什么“promise2”中的地图“无法读取未定义的属性'map'”。我不知道我是否可以在同一个函数中使用 2 个地图函数。
    • 这表明从 api 返回的 JSON 中没有 items 属性。你确定是格式吗?试试 console.log(json) 看看输出是什么...
    【解决方案2】:

    使用 Promise.all():

    var p1 = Promise.resolve(3);
    var p2 = 1337;
    var p3 = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, "foo");
    }); 
    
    Promise.all([p1, p2, p3]).then(values => { 
      console.log(values); // [3, 1337, "foo"] 
    });

    参考:https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

    【讨论】:

      【解决方案3】:

      你可以使用 Promise.all,它会在所有 Promise 都正常时解决,如果有任何失败则拒绝。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

      【讨论】:

        猜你喜欢
        • 2021-02-21
        • 2016-01-11
        • 2019-02-08
        • 2021-05-24
        • 1970-01-01
        • 2020-05-23
        • 1970-01-01
        • 2019-04-17
        • 1970-01-01
        相关资源
        最近更新 更多