How to add new data to the state ? Here is the code:

 import React, { Component } from 'react'; class MetricaGoals extends Component { constructor() { super(); this.state = { metricaGoalsList : [] metricaGoalsData : [] } } componentDidMount() { const OATH_TOKEN = 'token'; const PROJECT_ID = '23077159'; fetch(`https://api-metrika.yandex.ru/management/v1/counter/23077159/goals ?oauth_token=${OATH_TOKEN}`) .then(response => response.json()) .then(data => { const DATA = data.goals this.setState({ metricaGoalsList: DATA }) }); let acc = []; for (var i = 0; i < this.state.metricaGoals.metricaGoalsList.length; i++) { fetch(`https://api-metrika.yandex.ru/stat/v1/data/bytime ?date1=2018-06-13 &date2=2018-07-13 &group=day &metrics=ym:s:goal${this.state.metricaGoals.metricaGoalsList.id}conversionRate, ym:s:goal${this.state.metricaGoals.metricaGoalsList.id}reaches &id=${PROJECT_ID} &oauth_token=${OATH_TOKEN}`) .then(response => response.json()) .then(data => { acc.push(data.data[0].metrics) this.setState({ metricaGoalsData: acc }) }) } } render() { return ( <div className="MetricaGoals"> <ul className="goals__list"> { this.state.metricaGoals.metricaGoalsList.map(i => { return ( <li key={i.id} className="goals__item"> {this.state.metricaGoalsData[0]} </li> ) }) } </ul> </div> ); } } export default MetricaGoals; 

Nothing is written to the array? Why? How to make it recorded?

  • You do not wait for a response from the server - ThisMan
  • @ThisMan async / await? - Egor Zholnin
  • Well, almost, here you have several places where you need to wait for an answer - ThisMan

1 answer 1

1 - setState is setState in itself, so if you called it, it does not guarantee that the state really changed
2 - you have a lot of requests that you do not wait

Try it like this (explained in the comments)

  componentDidMount() { const OATH_TOKEN = 'token'; const PROJECT_ID = '23077159'; fetch(`https://api-metrika.yandex.ru/management/v1/counter/23077159/goals ?oauth_token=${OATH_TOKEN}`) .then(response => response.json()) .then({goals} => { // у нас теперь есть goals let acc = []; const promisses = []; // массив промисов // добавим наши goals которые уже загрузились this.setState({metricaGoals: goals}); for (var i = 0; i < goals.metricaGoalsList.length; i++) { // добавляем запросы в массив promisses.push( fetch(`https://api-metrika.yandex.ru/stat/v1/data/bytime ?date1=2018-06-13 &date2=2018-07-13 &group=day &metrics=ym:s:goal${goals.metricaGoalsList.id}conversionRate, ym:s:goal${goals.metricaGoalsList.id}reaches &id=${PROJECT_ID} &oauth_token=${OATH_TOKEN}`) .then(response => response.json()) ); } return Promise.all(promisses); // вернет нам все значения всех промисов }) .then(metricaGoalsData => { // тут уже делайте что хотите с данными, они все готовы this.setState({ metricaGoalsData }) }) }; 
  • And why now if you display this.state.metricaGoalsData[0].data in render() , an error occurs, saying that data does not exist? Although if you print this.state.metricaGoalsData[0] , then this object will be data . Here is a screen - Egor Zholnin
  • Apparently, because I do not wait again. If you output propertyNames inside setTimeout , then everything is good, but if you output this.state.metricaGoalsData[0].data[0] through setTimeout error sometimes pops up. Why? Is it possible to do all this without error?) - Egor Zholnin