Получить данные в ReactJS - PullRequest
0 голосов
/ 28 ноября 2018

Есть запрос get в componentDidMount()

componentDidMount() {
   var manufacturers = []

   this.props.participants.map(participant => {
     Get("manufacturer/" + participant.id, "").then(result => {
      manufacturers.push(result)
      console.log(manufacturers)
    });
  });

  this.setState({
    participants: manufacturers
  })
}

. Этот console.log(manufacturers) показывает, что в массиве есть объекты, но состояние компонента пустое.Как правильно установить его после извлечения данных?

Код функции Get():

const Config = require('Config')
export async function Get(type, userData) {
    let BaseURL = Config.serverUrl;
    let result = {};
    if(userData)
        result = await fetch(BaseURL+type, {
                method: 'GET',
                headers: new Headers({
                    'Authorization': 'Bearer ' + userData,
                    'Content-Type': 'application/json'
                })
        });
    else
        result = await fetch(BaseURL+type, {
            method: 'GET',
            headers: new Headers({
                'Content-Type': 'application/json'
            })
        });
    let data = await result.json();
    return data;
}

Ответы [ 6 ]

0 голосов
/ 28 ноября 2018

вы всегда должны обновлять State в 'then' или перехватывать блок обещания, когда обещание разрешено / отклонено ... как показано ниже

componentDidMount() {
var manufacturers = []

this.props.participants.map(participant => {
 Get("manufacturer/" + participant.id, "").then(result => {
  manufacturers.push(result);

   this.setState({participants: manufacturers});
   console.log(manufacturers);

  });
 });
}

Поскольку ваша функция get возвращает обещание, которое является асинхронным вызовом, когда getФункция выполняется, она переходит на следующую строку кода перед разрешением в this.setState () в вашем случае, следовательно, не показывает обновленное состояние.Всегда помните, что setState () сам по себе является асинхронным, и если вам нужно выполнить какую-либо операцию после setState, сделайте это в необязательном аргументе обратного вызова setState (), например: -

this.setState((currentState)=>{
 // you can access the currentState here
 },()=>{
 //your callback... here you can access directly this.state since it is guranteed 
  //that it will be updated state always
});
0 голосов
/ 28 ноября 2018

Поскольку у вас есть несколько Get вызовов, и каждый из них async, вам придется подождать, пока весь результат не будет collected, а затем установить его в состояние.Вы можете сделать это с помощью Promise.all, который может wait для всех Get вызовов, которые должны быть разрешены в первую очередь, а затем установить данные в состояние.

Я бы сначала создал функцию asyncи вызовите его в componentDidMount.

componentDidMount() {
  this.fetchAllData();
}

Затем внутри этого метода дождитесь разрешения всех Promises и установите его в состояние, как только мы получим данные.Возможно, вам придется заключить всю функцию в блок try..catch, чтобы в случае отклонения обещания из-за сбоя сетевого вызова вы могли обработать его соответствующим образом.

fetchAllData = async () => {
  const manufacturers = await Promise.all(
    this.props.participants.map(participant => 
      Get("manufacturer/" + participant.id, ""))
  )
  this.setState(manufacturers)
};
0 голосов
/ 28 ноября 2018

Инициализировать состояние перед вызовом метода ComponentDidMount:

constructor() {
    super();
    this.state = { participants:null }
}
0 голосов
/ 28 ноября 2018

Проблема связана с асинхронной логикой.Использование this.setState() за пределами then() выборки приводит к тому, что свойство manufacturers становится пустым.

Сложность в вашем случае заключается в том, что вам необходимо разрешить несколько запросов параллельно перед обновлением состояния.Это можно сделать с помощью функции Promise.all():

componentDidMount() {
  Promise.all(this.props.participants.map(participant =>
    Get("manufacturer/" + participant.id, "")
  ).then(results => {
    this.setState({
      participants: results // or results.map(result => result.data()) ...
    })
 })
}
0 голосов
/ 28 ноября 2018

Вы должны переместить ваш this.setState внутрь .then.Не знаю точно, почему вы сначала отправляете данные в массив производителей.Если вы используете этот массив для чего-то.Если у вас уже есть результат в состоянии, вам, вероятно, не понадобится массив производителей.Если нет .. Вы можете просто установить состояние с результатом, как показано ниже:

componentDidMount() {
   var manufacturers = []

   this.props.participants.map(participant => {
     Get("manufacturer/" + participant.id, "").then(result => {
      manufacturers.push(result) // Do you need this?
      console.log(manufacturers)
        this.setState({
          participants: result
        })
    });
  });
}
0 голосов
/ 28 ноября 2018

Вам нужно установить состояние в обратном вызове Получить обещание

componentDidMount() {
   var manufacturers = []

   this.props.participants.map(participant => {
     Get("manufacturer/" + participant.id, "").then(result => {
      manufacturers.push(result)
      console.log(manufacturers)
      this.setState({
        participants: manufacturers
      })
    });
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...