Как манипулировать ответом выборки для одиночного объекта JSON в реагирующем - PullRequest
0 голосов
/ 10 июня 2018

Я создаю свое первое мобильное приложение, использующее реагирующее.Я использую Axios для получения данных с веб-сайта WordPress.

Мне удалось успешно получить данные из массива JSON со списком музыкальных треков.Затем я вставил данные в переменную state.Затем я использовал функцию .map для отображения содержимого на экране.Вот рабочий пример кода:

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';

export default class FreshTracks extends Component {
    state={tracks:[]}
    componentDidMount(){
        axios.get("https://<URL for JSON list of tracks>")
            .then(response => this.setState({tracks:response.data}))
            .catch(function(error) {
                console.log('Fetch error: ' + error.message);
                });
    }  
    renderTracks(){
        return this.state.tracks.map (track =>
            <View key={track.id}>
                <Text>{track.title.rendered}</Text>
                <Text>{track.content.rendered}</Text>
            </View>
        )  
    }
    render() {
        return (
            <View>    
                {this.renderTracks()}
            </View>
        );
    }
}

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

Сначала я попытался сохранить тот же код, только изменив URL.Я получаю Fetch error: this.state.tracks.map is not a function.Я пытался console.log(this.state.tracks) до return в renderTracks(), и данные возвращались в консоли как объект, именно так, как и должно быть.

Затем я попытался изменить инициализацию state на: state={tracks:*{}*} вместо state={tracks:*[]*}.Кроме того, я изменил функцию renderTracks() на:

renderTracks(){
        return (
            <View>
                <Text>{this.state.tracks.id}</Text>
                <Text>{this.state.tracks.slug}</Text>
                <Text>{this.state.tracks.title.rendered}</Text>
                <Text>{this.state.tracks.content.rendered}</Text>
            </View>
        )
    }

Этот способ частично работает. Доступ к данным на одном уровне, например, this.state.tracks.id или this.state.tracks.slug, работает должным образом.Доступ к многоуровневым данным, таким как this.state.tracks.title.rendered, приводит к ошибке:

Cannot read property 'rendered' of undefined

Что мне нужно сделать, чтобы правильно получить данные из одного объекта JSON?

1 Ответ

0 голосов
/ 10 июня 2018

У объекта JSON нет метода map().Таким образом, ваш код, который предполагал, что this.state.tracks является массивом, потерпит крах.

Вместо этого вы сначала хотите сохранить this.state.track как null, а затем заполнить его объектом.Не забудьте проверить null в рендере и показать какой-нибудь заполнитель.

Что-то подобное, вероятно, будет работать?

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';

export default class FreshTracks extends Component {
  state = {track: null};

  componentDidMount(){
    axios.get("https://<your URL for a single track>")
         .then(response => this.setState({track:response.data}))
         .catch(function(error) {
           console.log('Fetch error: ' + error.message);
         });
  }  

  render() {
    const track = this.state.track;
    if (track === null) {
      return <View><Text>Loading...</Text></View>;
    }

    return (
      <View>
        <Text>{track.title.rendered}</Text>
        <Text>{track.content.rendered}</Text>
      </View>
    );
  }
}
...