Как правильно получить () JSON в React - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь получить некоторые данные JSON с URL-адреса.Затем я устанавливаю свое состояние как часть этих данных.

В моем методе рендеринга я хотел бы отобразить эти данные, используя map()

.Стоит столкнуться с тем, что, поскольку для извлечения данных требуется некоторое время, состояние все еще устанавливается равным нулю, когда он пытается его отобразить.

Другая проблема, с которой я сталкиваюсь, заключается в том, что моя функция getData () кажетсяогонь несколько раз каждые несколько секунд.Если я добавляю консольный журнал в конце, он регистрирует его снова и снова.

Кто-нибудь сможет дать мне знать, если увидит, что я что-то делаю не так?

Мой код такойследует:

getData = () => {
    let _this = this
    fetch('https://my-data-link.com')
    .then(
      response => {
        if (response.status !== 200) {
          console.log('Looks like there was a problem. Status Code: ' +
            response.status);
          return;
        }

        // Examine the text in the response
        response.json().then(
          data => {
            _this.setState({data: data.searchResults.filter(d => d.salesInfo.pricing.monthlyPayment <= _this.state.monthlyMax)})
          }
        );
      }
    )
    .catch(function(err) {
      console.log('Fetch Error :-S', err);
    });
    
    // Adding a console log here is when I noticed that the code keeps firing.
  }

  renderData = () => {
    let vehicles = "Loading..."
    let _this = this
    this.getData()
    setTimeout(function(){
      vehicles = _this.state.data.map(vehicle => (
        <h1>{vehicle.make}</h1>
      ))
      return vehicles
    }, 6000);

    return vehicles
  }
  
  render() {
    return (
      {this.state.formSubmitted > 0 &&
        <div>
          <h3 className="ch-mt--4">Recommended vehicles</h3>
          {this.renderData()}
        </div>
      }
    )
  }

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Вы должны вызвать getData в componentDidMount следующим образом:

componentDidMount() {
  this.getData()
}

Более того, вы не можете вызвать setState в методе рендеринга, это будет бесконечный цикл, так как после установки состояния render вызывается метод, поскольку renderData - это состояние установки, которое вызывается в render методе

Вместо setTimeOut вы должны выполнить следующее в методе рендеринга

// in return of render method. It will display data from state after api call
{this.state.data && this.state.data.map(vehicle => (
    <h1>{vehicle.make}</h1>
))}
0 голосов
/ 23 февраля 2019

У вас есть две проблемы

Первый: Вы вызываете getData в методе рендеринга, а в getData вы вызываете setState, который, по сути, запускает цикл.Запустите его в componentDidMount, если его нужно запустить только один раз при монтировании компонента.

Секунда: Вместо setTimeout, который не является надежным, вы должны инициализировать данные состояния как пустой массив вконструктор

constructor(props) {
    super(props);
    this.state = {
        data: [];
    }
}
componentDidMount() {
     this.getData();
}

getData = () => {
    let _this = this
    fetch('https://my-data-link.com')
    .then(
      response => {
        if (response.status !== 200) {
          console.log('Looks like there was a problem. Status Code: ' +
            response.status);
          return;
        }

        // Examine the text in the response
        response.json().then(
          data => {
            _this.setState({data: data.searchResults.filter(d => d.salesInfo.pricing.monthlyPayment <= _this.state.monthlyMax)})
          }
        );
      }
    )
    .catch(function(err) {
      console.log('Fetch Error :-S', err);
    });


  }

  renderData = () => {
    let vehicles = "Loading..."
    if(this.state.data.length === 0) {
        return vehicles;
    }
    return this.state.data.map(vehicle => (
        <h1>{vehicle.make}</h1>
    ));
  }

  render() {
    return (
      {this.state.formSubmitted > 0 &&
        <div>
          <h3 className="ch-mt--4">Recommended vehicles</h3>
          {this.renderData()}
        </div>
      }
    )
  }
...