Изменение результата Fetch в API - PullRequest
0 голосов
/ 29 апреля 2020

Я начинающий разработчик React и столкнулся с этой проблемой при получении API. API, который я использую, возвращает массив объектов разных символов. Проблема в том, что некоторые параметры объекта имеют ссылку в качестве значения, что означает, что я не могу просто отобразить

с ключом и его значением. Вот фрагмент объекта из этого API:

{
    "url":"link",
    "name":"Alys Karstark",
    "gender":"Female",
    "culture":"Northmen",
    "born":"",
    "titles":["Lady of Winterfell"],
    "spouse":"link",
    "allegiances":["link",
    "link"],
    "books":["link"],
}

Итак, я подумал, что должен построить метод, который по прибытии исходного списка будет go через объекты символов и go через ключи, на которых есть ссылки, и извлекают упомянутые ссылки, вытягивая их название для отображения. После этого я выбираю случайный объект персонажа из отсортированного списка и отображаю его.

Вот выборка при монтировании:

componentDidMount(){
  fetch(defaultQuery)
  .then(response => response.json())
  .then(result => {
    this.setState({result: result})
    this.optimizeCharacterInfo()
  })
  .catch(error => error)
}

А вот функция, которая выполняет оптимизацию:

getRandomChar(){
  this.setState({randomCharacter: _.sample(this.state.optimizedList)})
}

 optimizeCharacterInfo() {
    const optimizedList = this.state.result.map(char => {
      for (let key in char) {
        if (linkKeys.includes(key)) {
          if (!Array.isArray(char[key])) char[key] = [char[key]];
          const names = [];
          char[key].forEach(link => {
            fetch(link)
              .then(response => response.json())
              .then(result => {
                names.push(result.name);
                char[key] = names;
              })
              .catch(error => error);
          });
        }
      }
      char.isOptimized = true;
      return char;
    });
    this.setState({ optimizedList: optimizedList });
    this.getRandomChar();
  }

  render() {
    const { randomCharacter } = this.state;
    return (
      <div>
        <Header headerText={homeText} />
        {randomCharacter && randomCharacter.isOptimized ? (
          <MainPage randomCharacter={randomCharacter} />
        ) : null}
      </div>
    );
  }

Хотя по какой-то причине, когда я загружаю вверх по странице это выглядит так:

name: Alyn Velaryon
gender: Male
culture: Valyrian
born: In 115 AC or later, at Hull, Driftmark
died: In or between 171 AC and 176 AC, at sea
titles: Lord of the TidesMaster of DriftmarkAdmiralMaster of ships
aliases: Alyn of HullThe OakenfistLord Oakenfist
father:
mother:
spouse: link
allegiances: link

и я ожидаю:

name: Alyn Velaryon
gender: Male
culture: Valyrian
born: In 115 AC or later, at Hull, Driftmark
died: In or between 171 AC and 176 AC, at sea
titles: Lord of the TidesMaster of DriftmarkAdmiralMaster of ships
aliases: Alyn of HullThe OakenfistLord Oakenfist
father:
mother:
spouse: name of the spouse
allegiances: allegiance 1, allegiance 2

Это означает, что он не использовал отфильтрованный список. После того, как я посмотрел в инструментах разработки, и список, и случайный символ перевели все ссылки в извлеченные имена. Так что же дает? Я собираюсь догадаться, что это можно решить, выполнив обещание, потому что, если я установлю тайм-аут на установку случайного символа, это сработает, но как бы я ни старался, я не смогу получить рабочее обещание. Как получить функцию, устанавливающую isOptimized в значение ТОЛЬКО, когда выбраны все необходимые ссылки?

1 Ответ

1 голос
/ 29 апреля 2020

setState asyn c, поэтому вызов optimizeCharacterInfo сразу после этого не будет делать то, что вы хотите, так как result еще не в состоянии.

К счастью setState принимает второй параметр, который запускается после установки состояния.

, поэтому измените

.then(result => {
    this.setState({result: result})
    this.optimizeCharacterInfo()
  })

на

.then(result => {
    this.setState({result: result}, this.optimizeCharacterInfo)
  })

, то же самое относится и к optimizeCharacterInfo поэтому измените также

this.setState({ optimizedList: optimizedList })
this.getRandomChar()

на

this.setState({ optimizedList: optimizedList }, this.getRandomChar)
...