简体   繁体   中英

How to manipulate fetch response for single object JSON in react-native

I am creating my first mobile app using react-native. I am using axios to fetch data from a wordpress website.

I managed to successfully get data from an array JSON with a list of musical tracks. I then inserted data into a state variable. Then, I used .map function to show contents on screen. Here's a working sample code:

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>
        );
    }
}

Now, I am struggling to get data from a single object JSON, one musical track.

At first, I tried keeping the same code, only changing the url. I get Fetch error: this.state.tracks.map is not a function . I tried console.log(this.state.tracks) before the return in renderTracks() and the data is returned in the console as an object, exactly how it should.

I then tried to change the state initialization to: state={tracks:*{}*} instead of state={tracks:*[]*} . Also, i changed the renderTracks() function to:

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 way is partially working Accessing data on a single level like this.state.tracks.id or this.state.tracks.slug is working as expected. Accessing multi-level data like this.state.tracks.title.rendered throws an error:

Cannot read property 'rendered' of undefined

What should I do to correctly get data from single object JSON?

A JSON object doesn't have a map() method. So your code that assumed this.state.tracks is an array would crash.

Instead, you want to keep this.state.track as null at first, and then fill it in with an object. Don't forget to check for null in render and show some kind of a placeholder.

Something like this will probably work?

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>
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM