ReactJS ошибка при получении объекта из топора ios вызов API - PullRequest
0 голосов
/ 09 февраля 2020

У меня есть следующий код:

import React, { Component } from 'react';
import axios from 'axios';

class Dashboard extends Component {
     state = {
         name : 'randomname',
         apiData: {}
};

componentDidMount() {
  axios.get('https://api_url/getdata)
    .then(res => {
        const apiData = res.data
        this.setState({apiData});
    });
}

render() {
  const { name, apiData} = this.state;

  //THIS WORKS
  var objTest = [{game_id: 2}]; //This is returned from apical
  console.log(objTest[0].game_id);

  console.log(apiData); //logs the following: [{game_id: 2}]
  console.log(apiData[0]); //logs the following: {game_id: 2}
  console.log(apiData[0].game_id); //Error occurs See error below

  return (  
    <div className="wrap">
         TESTING
    </div>
  );
}
}

export default Dashboard;

При тестировании и попытке получить game_id, используя: console.log(apiData[0].game_id); Я получаю следующую ошибку:

TypeError: undefined не является объектом (оценивает 'apiData [0] .game_id')

Я хотел бы знать, почему это работает, когда я объявляю переменную и присваиваю ей те же значения, что и API звонок возвращается. Но это не работает, тогда я назначаю вызов API для apiData. Он может получить доступ только к apiData[0], который возвращает {game_id:2}, но не может получить доступ к apiData [0] .game_id.

Спасибо за помощь!

Ответы [ 3 ]

0 голосов
/ 09 февраля 2020

ComponentDidMount запускается после загрузки метода рендеринга. Это означает, что console.log (apiData [0]) вызывает состояние по умолчанию перед вызовом метода componentDidMount.

Состояние по умолчанию - это пустой объект, а не массив. Таким образом, индекс 0 apiData - это ничто. Изменение состояния по умолчанию на apiData: [{game_id: null}] даст вам результат, и состояние изменится после запуска componentDidMount и успешного вызова API.

Это, однако, не лучший подход. Просто чтобы все было понятно и понятно.

0 голосов
/ 17 февраля 2020

Просто определили один флаг в состоянии и проверьте, доступны ли ваши данные, как только вы получите данные, измените этот флаг и соответственно загрузите элемент компонента.

см. Приведенное ниже решение для вашей задачи.

import React, { Component } from 'react';
import axios from 'axios';

class Dashboard extends Component {
     state = {
         loading:true,
         name : 'randomname',
         apiData: {}
};

componentDidMount() {
  axios.get('https://api_url/getdata').then(res => {
        this.setState({apiData:res.data, loading:false});
    });
}

render() {
  const { name, apiData, loading} = this.state;

  //THIS WORKS
  var objTest = [{game_id: 2}]; //This is returned from apical
  console.log(objTest[0].game_id);

  console.log(apiData); //logs the following: [{game_id: 2}]
  console.log(apiData[0]); //logs the following: {game_id: 2}
  console.log(apiData[0].game_id); //Error occurs See error below

  return (  
    <div className="wrap">
         {loading ? <div>Loading ...</div> : <div className="wrap">TESTING</div>}
    </div>
  );
}
}

export default Dashboard;
0 голосов
/ 09 февраля 2020

Основной вопрос здесь - порядок методов жизненного цикла. На этапе монтирования вызывается конструктор, а затем метод рендеринга. ComponentDidMount еще не вызывается, и, следовательно, ваше состояние пусто. Причина, по которой вы не получаете сообщение об ошибке при входе в систему apiData или apiData [0], заключается в том, что он просто регистрирует пустой массив или объект во время первоначального вызова рендеринга (фаза монтирования), а затем фактический объект во время второго рендеринга после componentDidMount (фаза обновления). Но когда вы пытаетесь вызвать свойство (game_id), вы получаете ошибку (неопределенную) на этапе монтирования, так как вы вызываете его для пустого массива / объекта.

Решением является проверка существования родительского объекта перед вызовом свойства для него, например, с помощью необязательного связывания (новое будущее JS2020), которое проверяет apiData [0], ошибку следует исправить, просто добавив py "?" после объекта. Вы также можете использовать другие методы для более старых JS.

console.log(apiData[0]?.game_id)
...