如何在本机反应中解析json数据
Posted
技术标签:
【中文标题】如何在本机反应中解析json数据【英文标题】:How to parse json data in react native 【发布时间】:2019-05-15 14:01:07 【问题描述】:您好,我是 React 原生开发的新手,请帮助我如何解析以下数据
这是我的代码
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"
]
]
【问题讨论】:
React Native 中不需要解析数据,可以直接访问对象,如response[0].Pharmacy.name
@rutvik-bhatt 如果您不介意,请用 for 循环添加答案,我没听清楚
【参考方案1】:
问题在于 json 响应是一个对象数组。您需要从数组中选择对象。
例如,如果您想要数组中的第一项,您可以执行以下操作
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
从那里捕获数据。
所以console.log(first.Pharmacy.Name)
应该给你 Hillcrest MOB Pharmacy
您似乎也在尝试创建和显示这些药房的列表。根据您拥有的项目数量,有几种方法可以做到这一点。然而,最高效和最简单的是使用 FlatList。如果由于任何原因超出页面,这将处理视图。
所以让我们设置 FlatList。
首先,从 react-native 导入 FlatList
。
其次将你的 componentDidMount 中的 setState 调用更改为
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 ()
return (
<View style=flex: 1>
<FlatList
data=this.state.dataSource
keyExtractor=this.keyExtractor
renderItem=this.renderItem
/>
</View>
);
那么它应该看起来像这样。显然缺少样式,我使用了替代图像。但这应该是您正在寻找的想法。
希望这足以获取您需要的数据。
更新
这是一个完整工作的组件,它呈现一个类似于上面的列表
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
项目显示为单个列表。
这可以通过对 responseJson 执行 map 和 reduce 来完成,因此 setState
调用可以更新为以下内容
this.setState(
isloading: false,
dataSource: responseJson.map(item => item.ReadyForPickups).reduce((acc, currValue) => return acc.concat(currValue); , [])
);
这会将 ReadyForPickup 项目分组为一个长列表,如下所示:
[
"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
函数应该被更新以显示列表。
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>
);
【讨论】:
我想获取所有 rxdrugnames ,请您帮忙 @UmaAchanta 我已经更新了我的答案,以展示如何在 FlatList 中使用这些数据。获取 RxDrugName 时需要小心,因为 ReadyForPickups 是一个对象数组,你永远不知道它是否为空。 @UmaAchanta,一切顺利吗? @UmaAchanta 我刚刚编辑了我的帖子,以便有一个完整的工作组件。您只需要创建一个样式文件。因为没有你的图片,所以我更改了图片 uri。 这只会给第一项权利'ReadyForPickups[0]'【参考方案2】:您的 responseJson
是 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"
]
所以你应该
.then((responseJson) =>
this.setState(
isLoading: false,
dataSource: responseJson
);
在render()
中,您可以map()
dataSource
中的每个项目并调用renderItem()
作为您的代码:
render()
return (
<View>
this.state.dataSource.map(item => this.renderItem(item))
</View>
)
在renderItem(item)
中,item
现在是上面格式的JSON对象,你可以轻松渲染它。
renderItem(obj)
const item = (obj.ReadyForPickups || [])[0] || ;
// this will secure your app not crash when item is invalid data.
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数据的主要内容,如果未能解决你的问题,请参考以下文章