Реагировать - получить несколько API

Я хочу сделать запрос на получение к нескольким API одновременно с двух разных URL-адресов, а затем я хочу просто обновить массив «items» в состоянии с новым свойством «img», а не перезаписывать его. Я хочу сохранить и свойства в первом запросе. Вот моя попытка.

   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.info(newState);
          this.setState(newState);
        })
        .catch((error) => {
          console.info(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.info(newState);
          this.setState(newState);
        })
        .catch((error) => {
          console.info(error)
        });
    }
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
3
0
3 260
3

Ответы 3

Вы можете использовать Promise.all, он разрешится, когда все обещания будут выполнены, или отклонить, если какой-либо из них не сработает.

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

Используйте 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.info(values); // [3, 1337, "foo"] 
});

Ссылка: https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Вы абсолютно можете вызвать два отдельных 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)
})

Спасибо за ответ, я попробовал ваше решение, но не могли бы вы проверить мой обновленный вопрос? это так неприятно!

develop05 03.09.2018 15:25

Я все еще немного запутался, вы пытаетесь создать объект items, который выглядит так: {{itemId: 123, name: test1}, {img: ...}} или вот так: {{itemId: 123, name: test1, img: ...}}

MattC 04.09.2018 22:00

Как и последний {{itemId: 123, name: test1, img: ...}}

develop05 04.09.2018 22:37

Ваш ответ кажется правильным, но он дает мне эту ошибку, я не знаю, почему «Невозможно прочитать свойство 'map' of undefined» для карты в «обещании2». Я не знаю, могу ли я использовать две функции карты в одной функции.

develop05 05.09.2018 10:49

Это будет означать, что в JSON, возвращаемом из api, нет свойства items. Вы уверены, что это формат? Попробуйте console.info (json) и посмотрите, что получится ...

MattC 05.09.2018 13:10

Другие вопросы по теме