ReactJS и axios, проблемы с доступом к вложенным объектам из ответа JSON - PullRequest
1 голос
/ 07 октября 2019

У меня проблемы с попыткой получить доступ к значениям в этом ответе JSON от wagtail CMS:

{
  "meta": {
    "total_count": 1
  },
  "items": [
    {
      "id": 13,
      "meta": {
        "type": "home.HomePage",
        "detail_url": "http://localhost/api/v2/pages/13/",
        "html_url": "http://localhost/frontpage/",
        "slug": "frontpage",
        "first_published_at": "2019-10-07T03:48:09.199838Z"
      },
      "title": "FrontPage",
      "body": [
        {
          "type": "heading",
          "value": "hello",
          "id": "44ab7cbf-24ce-4db1-8822-9a24e91385d9"
        },
        {
          "type": "paragraph",
          "value": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed et leo ac  velit venenatis elementum. Duis viverra velit eget justo consectetur  feugiat. Curabitur congue orci orci, vel iaculis augue pharetra nec.  Cras sit amet enim eu massa varius congue. Maecenas et tellus vitae urna  blandit ullamcorper sed in erat. Nam tristique justo vel ipsum  imperdiet, quis tempus enim euismod. Nunc eget condimentum neque, in  pretium elit. Proin tincidunt viverra nulla id blandit. Duis nec diam  tristique massa euismod varius quis ac ex. Suspendisse potenti. </p>",
          "id": "f5913d9e-294c-4f45-9147-909bec1f404c"
        },
        {
          "type": "paragraph",
          "value": "<p>Nulla sollicitudin mauris in turpis faucibus feugiat. Praesent vel neque  vitae erat tempor semper faucibus non magna. Vestibulum velit risus,  tempor at ultricies quis, auctor vitae augue. Vestibulum sit amet  porttitor tortor, ut tempor nisi. Sed nulla lacus, sodales eu risus eu,  tincidunt tempor quam. Mauris fringilla vitae est vitae hendrerit. In  facilisis libero in sagittis iaculis. Aenean ultrices elit tincidunt,  interdum metus vel, finibus mi. Aenean tincidunt purus ac mauris  hendrerit hendrerit. Phasellus sit amet ipsum nisl. Fusce in nisi  feugiat, condimentum lectus sit amet, sollicitudin dolor. Nulla  vulputate, felis scelerisque lobortis ornare, nisl sapien convallis  felis, ut scelerisque est purus vitae ipsum. </p>",
          "id": "f3769b82-5cad-4be7-a179-5800e24e6347"
        }
      ]
    }
  ]
}

В целях тестирования я получаю ответ от бэкэнда, используя этот код:

class HomePage extends Component {
  constructor(props) {
    super(props);

    this.state = {
        home: [],
    };
  }

  componentDidMount() {
    this.getHome();
  }

  getHome() {
      axios
        .get('http://127.0.0.1:8000/api/v2/pages/?type=home.HomePage&fields=body')
        .then(res => {
            this.setState({home: res.data});
        })
        .catch(err => {
            console.log(err);
        });
  }

    render() {
        const { classes } = this.props;
        return(
            <div>
              {Object.entries(this.state.home).map(([key, value]) =>
                  <p>{key} : {value}</p>
              )}
            </div>
        )
    }
}

Ошибка, которую я получаю после компиляции:

Objects are not valid as a React child (found: object with keys {total_count})

Поэтому я пытаюсь пойти на один уровень глубже с this.state.home.meta.total_count

Реагирует: TypeError: this.state.home.meta is undefined

Есть идеи о том, что здесь происходит, или есть ли лучший способ получить доступ к этим данным?

Ответы [ 3 ]

2 голосов
/ 07 октября 2019

Ваша функция рендеринга не будет отображать объект, потому что это не текст или недопустимый дочерний элемент React, как говорится в сообщении об ошибке.

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

 render() {
    const { classes } = this.props;
    return(
        <div>
          {Object.entries(this.state.home).map(([key, value]) =>
              <p>{key} : {typeof(value) === 'object' ? JSON.stringify(value) : value}</p>
          )}
        </div>
    )
}

Проверьте код здесь:

Edit laughing-wozniak-07lsx

Вторая проблема, с которой вы столкнулись, когда вы попытались перейти на один уровень глубиной, изменив его на this.state.home.meta.total_count, это потому, что home.meta.total_count не существует в первый раз, когда ваш компонент рендерит, только после вызова componentDidMount, поэтому обязательно проверьте свои переменные и посмотритеесли они не равны нулю или не определены до их использования.

0 голосов
/ 07 октября 2019

Ваш компонент монтируется, но вы еще не получили ответ от API. Вам нужно дождаться завершения ответа API и получить доступ к значениям данных.

Попробуйте: -

class HomePage extends Component {
  constructor(props) {
    super(props);

    this.state = {
        home: [],
        isLoading: true
    };
  }

  componentDidMount() {
    this.getHome();
  }

  getHome() {
      axios
        .get('http://127.0.0.1:8000/api/v2/pages/?type=home.HomePage&fields=body')
        .then(res => {
            this.setState({home: res.data, isLoading: false});
        })
        .catch(err => {
            this.setState({isLoading: false});
            console.log(err);
        });
  }

    render() {
        const { classes } = this.props;
        return(
            isLoading && (
                <div>
                  {Object.entries(this.state.home).map(([key, value]) =>
                      <p>{key} : {value}</p>
                  )}
                </div>
            )
        )
    }
}

И НЕ визуализируйте непосредственно объект внутри JSX (как вы это делаете в настоящее время). Попробуйте добавить правильную логику для прохождения этого res.data. В противном случае вы увидите эту ошибку: Objects are not valid as a React child

0 голосов
/ 07 октября 2019

Вы должны добавить некоторые дополнительные проверки для учета вложенных объектов. Нечто похожее на это:

renderValues = (values) => {
  if (values) {
    return (
      <div>
        {values.map((value, key) => {
           if (typeof value === 'object') {
              return this.renderValues(value);
           }
           return <p>{key} : {value}</p>;
        })}
      </div>
    );
  }
  return null;
}

render() {
  return (
    <div>
      {this.renderValues(Object.entries(this.state.home))}
    </div>
  )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...