В componentDidMount() есть запрос на получение
componentDidMount() {
var manufacturers = []
this.props.participants.map(participant => {
Get("manufacturer/" + participant.id, "").then(result => {
manufacturers.push(result)
console.info(manufacturers)
});
});
this.setState({
participants: manufacturers
})
}
Этот console.info(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;
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вам нужно установитьState в обратном вызове Get обещания
componentDidMount() {
var manufacturers = []
this.props.participants.map(participant => {
Get("manufacturer/" + participant.id, "").then(result => {
manufacturers.push(result)
console.info(manufacturers)
this.setState({
participants: manufacturers
})
});
});
}
Вам следует переместить 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.info(manufacturers)
this.setState({
participants: result
})
});
});
}
Проблема связана с асинхронной логикой. Использование 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()) ...
})
})
}
Инициализируйте состояние перед вызовом метода ComponentDidMount:
constructor() {
super();
this.state = { participants:null }
}
Поскольку у вас есть несколько вызовов Get, и каждый из них - async, вам придется подождать, пока весь результат не будет collected, а затем установить его в состояние. Вы можете сделать это, используя Promise.all, который может сначала разрешить все вызовы wait, а затем установить данные в состояние.
Сначала я бы создал функцию Get и вызвал ее в async.
componentDidMount() {
this.fetchAllData();
}
Затем внутри этого метода дождитесь разрешения всех componentDidMount и установите его в состояние, когда у нас есть данные. вам, возможно, придется обернуть всю функцию внутри блока Promises, чтобы, если есть какое-либо отклонение обещания из-за сбоя сетевого вызова, вы могли обработать его соответствующим образом.
fetchAllData = async () => {
const manufacturers = await Promise.all(
this.props.participants.map(participant =>
Get("manufacturer/" + participant.id, ""))
)
this.setState(manufacturers)
};
вы всегда должны обновлять State в 'then' или поймать блок обещания, когда обещание разрешено / отклонено ... как показано ниже
componentDidMount() {
var manufacturers = []
this.props.participants.map(participant => {
Get("manufacturer/" + participant.id, "").then(result => {
manufacturers.push(result);
this.setState({participants: manufacturers});
console.info(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
});