如何在React Native中解析JSON数据 [英] How to parse json data in react native

查看:126
本文介绍了如何在React Native中解析JSON数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是React本机开发的新手,如何解析以下数据请帮助我

hi I am new to React native development, how to parse following data please help me

这是我的代码

componentDidMount() {
fetch('https://api.myjson.com/bins/96ebw')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.Pharmacy,
}, 

);
})
.catch((error) => {
console.error(error);
});
}

renderItem(dataSource) {
const { List: list } = this.state.dataSource
const { item } = dataSource;

return (
<View style={styles.itemBlock}>
<View style={styles.itemMeta}>
<Text style={styles.itemName}>{item.RxDrugName}</Text>
<Text style={styles.itemLastMessage}>{item.RxNumber}</Text>
</View>

<View style={styles.footerStyle}>
<View style={{ paddingVertical: 10 }}>
<Text style={styles.status}>{ item.StoreNumber }</Text>
</View>

<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Image source={require('../assets/right_arrow_blue.png')} />
</View>

</View>
</View>
);
}

json是

[
  {
    "Pharmacy": {
      "Name": "Hillcrest MOB Pharmacy",
      "StoreNumber": "254",
      "Address": {
        "StreetAddress": "50 Hillcrest Medical Blvd Ste 200-1",
        "City": "WACO",
        "State": "TX",
        "Zip": "76712"
      },
      "IsDefault": false
    },
    "ReadyForPickups": [
      {
        "RxDrugName": "Tizanidine HCL 4mg Caps",
        "RxNumber": "6000295",
        "StoreNumber": "254",
        "PatientPay": "15.59"
      }
    ]
  },

  {
    "Pharmacy": {
      "Name": "Waco Pharmacy",
      "StoreNumber": "251",
      "Address": {
        "StreetAddress": "1412 N Valley Mills, Suite 116",
        "City": "WACO",
        "State": "TX",
        "Zip": "76710"
      },
      "IsDefault": false
    },
    "ReadyForPickups": [
      {
        "RxDrugName": "Fluoxetine HCL 40mg Caps",
        "RxNumber": "6000233",
        "StoreNumber": "251",
        "PatientPay": "17.3"
      }
    ]
  }

]

推荐答案

问题是json响应是对象数组.您需要从数组中选择对象.

The problem is that the json response is an array of objects. You need to select the object from the array.

例如,如果您想要数组中的第一项,则可以执行以下操作

For example, if you want the first item in the array you could do the following

const first = jsonResponse[0]

{
  "Pharmacy":{
    "Name":"Hillcrest MOB Pharmacy",
    "StoreNumber":"254",
    "Address":{
      "StreetAddress":"50 Hillcrest Medical Blvd Ste 200-1",
      "City":"WACO",
      "State":"TX",
      "Zip":"76712"
    },
    "IsDefault":false
  },
  "ReadyForPickups":[
    {
      "RxDrugName":"Tizanidine HCL 4mg Caps",
      "RxNumber":"6000295",
      "StoreNumber":"254",
      "PatientPay":"15.59"
    }
  ]
}

现在,您可以尝试使用first.Pharmacy从那里捕获数据.

Now you can try using first.Pharmacy to capture the data from there.

所以console.log(first.Pharmacy.Name)应该给您Hillcrest MOB药房

So console.log(first.Pharmacy.Name) should give you Hillcrest MOB Pharmacy

您似乎也正在尝试创建并显示这些药房的列表.根据您拥有的物品数量,有两种方法可以做到这一点.但是,最有效和最简单的方法是使用FlatList.如果出于某种原因它延伸到页面之外,则将负责该视图.

It also looks like you are trying to create and display a list of these Pharmacies. Depending on the number of items you have there are a couple of ways to do that. However, the most performant and easiest is to use a FlatList. This will take care of the view if for any reason that it extends off of the page.

因此,让我们设置FlatList.

So let's set up the FlatList.

首先,从react-native导入FlatList.

Firstly, import FlatList from react-native.

第二次将componentDidMount中的setState调用更改为

Secondly change the setState call in your componentDidMount to be

this.setState({
  isLoading: false,
  dataSource: responseJson
}

添加以下方法

renderItem = ({item, index}) => {
  let { Pharmacy, ReadyForPickups } = item;

  if(!ReadyForPickups[0]) return null;
  let details = ReadyForPickups[0]

  return (
  <View style={styles.itemBlock}>
    <View style={styles.itemMeta}>
      <Text style={styles.itemName}>{details.RxDrugName}</Text>
      <Text style={styles.itemLastMessage}>{details.RxNumber}</Text>
    </View>

    <View style={styles.footerStyle}>
      <View style={{ paddingVertical: 10 }}>
        <Text style={styles.status}>{ details.StoreNumber }</Text>
      </View>

      <View style={{ justifyContent: 'center', alignItems: 'center' }}>
        <Image source={require('../assets/right_arrow_blue.png')} />
      </View>

    </View>
  </View>
  );
}

keyExtractor = (item, index) => {
  return index.toString();
}

然后您的render方法应该看起来像这样

Then your render method should look something like this

  render () {
      return (
        <View style={{flex: 1}}>
          <FlatList
            data={this.state.dataSource}
            keyExtractor={this.keyExtractor}
            renderItem={this.renderItem}
          />
        </View>
      );
    }

然后它应该看起来像这样.显然样式丢失了,我使用了替代图像.但这应该是您要寻找的想法.

Then it should look something like this. Obviously the stylings are missing and I used a substitute image. But this should be the idea of what you are looking for.

希望这足以获取所需的数据.

Hopefully that should be enough to get the data out that you require.

更新

这是一个完全正常工作的组件,它呈现与上面的列表相似的列表

Here is a fully working component that renders a list similar to the one above

import React, { Component } from 'react';
import { View, Text, FlatList, Image } from 'react-native';
import PropTypes from 'prop-types';

// import screens styles
import styles from './styles';

class Pharmacy extends Component {
  /**
   * Construct component class
   * @param {object} props
   */
  constructor (props: {}) {
    super(props);

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

  componentDidMount () {
    fetch('https://api.myjson.com/bins/96ebw')
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          isLoading: false,
          dataSource: responseJson
        });
      });
  }

  renderItem = ({item, index}) => {
    let { Pharmacy, ReadyForPickups } = item;

    if (!ReadyForPickups[0]) return null;
    let details = ReadyForPickups[0];

    return (
      <View style={styles.itemBlock}>
        <View style={styles.itemMeta}>
          <Text style={styles.itemName}>{details.RxDrugName}</Text>
          <Text style={styles.itemLastMessage}>{details.RxNumber}</Text>
        </View>

        <View style={styles.footerStyle}>
          <View style={{ paddingVertical: 10 }}>
            <Text style={styles.status}>{ details.StoreNumber }</Text>
          </View>

          <View style={{ justifyContent: 'center', alignItems: 'center' }}>
            <Image source={{uri: 'https://images.pexels.com/photos/949586/pexels-photo-949586.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'}}
              style={{height: 50, width: 50}}/>
          </View>

        </View>
      </View>
    );
  }

  keyExtractor = (item, index) => {
    return index.toString();
  }

  render () {
    return (
      <View style={{flex: 1}}>
        <FlatList
          data={this.state.dataSource}
          keyExtractor={this.keyExtractor}
          renderItem={this.renderItem}
        />
      </View>
    );
  }
}

export default Pharmacy;

更新2

与原始问题发布者聊天后,似乎他们希望只将ReadyForPickups项目显示为单个列表.

After a chat with the original question poster it seems that they want they only want to show the ReadyForPickups items as a single list.

这可以通过执行映射和减少responseJson来完成,以便可以将setState调用更新为以下内容

This can be done by performing a map and a reduce on the responseJson so the setState call can be updated to the following

this.setState({
  isloading: false,
  dataSource: responseJson.map(item => item.ReadyForPickups).reduce((acc, currValue) => { return acc.concat(currValue); }, [])
});

这会将ReadyForPickup项目分组为一个长列表,如下所示:

This will group the ReadyForPickup items into one long list as follows:

[
  {
    "RxDrugName":"Tizanidine HCL 4mg Caps",
    "RxNumber":"6000295",
    "StoreNumber":"254",
    "PatientPay":"15.59"
  },
  {
    "RxDrugName":"Hydroxychloroquine Sulfate 200 Tabs",
    "RxNumber":"6000339",
    "StoreNumber":"201",
    "PatientPay":"16.18"
  },
  {
    "RxDrugName":"Naratriptan HCL 2.5mg Tabs",
    "RxNumber":"6000300",
    "StoreNumber":"111",
    "PatientPay":"39.04"
  },
  {
    "RxDrugName":"Tizanidine HCL 4mg Caps",
    "RxNumber":"6000457",
    "StoreNumber":"08",
    "PatientPay":"15.59"
  },
  {
    "RxDrugName":"Lisinopril 20mg Tabs",
    "RxNumber":"6000318",
    "StoreNumber":"08",
    "PatientPay":"13.46"
  },
  {
    "RxDrugName":"Fluoxetine HCL 40mg Caps",
    "RxNumber":"6000233",
    "StoreNumber":"251",
    "PatientPay":"17.3"
  },
  {
    "RxDrugName":"Tizanidine HCL 4mg Caps",
    "RxNumber":"6000222",
    "StoreNumber":"232",
    "PatientPay":"15.59"
  },
  {
    "RxDrugName":"Memantine HCL 5mg Tabs",
    "RxNumber":"6000212",
    "StoreNumber":"231",
    "PatientPay":"17.99"
  },
  {
    "RxDrugName":"Clonidine HCL 0.1mg Tabs",
    "RxNumber":"6000339",
    "StoreNumber":"07",
    "PatientPay":"12.71"
  },
  {
    "RxDrugName":"Benazepril HCL 5mg Tabs",
    "RxNumber":"6000261",
    "StoreNumber":"06",
    "PatientPay":"13.45"
  },
  {
    "RxDrugName":"Clonidine HCL 0.1mg Tabs",
    "RxNumber":"6000524",
    "StoreNumber":"02",
    "PatientPay":"12.73"
  },
  {
    "RxDrugName":"Timolol Maleate 20mg Tabs",
    "RxNumber":"6000771",
    "StoreNumber":"02",
    "PatientPay":"15.33"
  },
  {
    "RxDrugName":"Benazepril HCL 5mg Tabs",
    "RxNumber":"6002370",
    "StoreNumber":"01",
    "PatientPay":"13.45"
  },
  {
    "RxDrugName":"Eliquis 5mg Tabs",
    "RxNumber":"6002609",
    "StoreNumber":"01",
    "PatientPay":"20.88"
  },
  {
    "RxDrugName":"Atorvastatin Calcium 20mg Tabs",
    "RxNumber":"6002602",
    "StoreNumber":"01",
    "PatientPay":"17.69"
  },
  {
    "RxDrugName    ":"Astagraf Xl 0.5mg Cp24",
    "RxNumber":"6000232",
    "StoreNumber":"278",
    "PatientPay":"15.33"
  },
  {
    "RxDrugName":"Ropinirole HCL 0.5mg Tabs",
    "RxNumber":"6000067",
    "StoreNumber":"112",
    "PatientPay":"14.75"
  },
  {
    "RxDrugName":"Ciprofloxacin HCL 0.3% Soln",
    "RxNumber":"6000217",
    "StoreNumber":"275",
    "PatientPay":"55.06"
  },
  {
    "RxDrugName":"Sotalol HCL 240mg Tabs",
    "RxNumber":"6000575",
    "StoreNumber":"09",
    "PatientPay":"17.5"
  }
]

要匹配新的数据源,应更新renderItem函数,以便显示列表.

To match the new dataSource the renderItem function should be updated so that it will display the list.

renderItem = ({item, index}) => {

  return (
  <View style={styles.itemBlock}>
    <View style={styles.itemMeta}>
      <Text style={styles.itemName}>{item.RxDrugName}</Text>
      <Text style={styles.itemLastMessage}>{item.RxNumber}</Text>
    </View>

    <View style={styles.footerStyle}>
      <View style={{ paddingVertical: 10 }}>
        <Text style={styles.status}>{item.StoreNumber }</Text>
      </View>

      <View style={{ justifyContent: 'center', alignItems: 'center' }}>
        <Image source={require('../assets/right_arrow_blue.png')} />
      </View>

    </View>
  </View>
  );
}

这篇关于如何在React Native中解析JSON数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆