嗨,我是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"
}
]
}
]
答案 0 :(得分:2)
问题在于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药房
您似乎也正在尝试创建并显示这些药房的列表。根据您拥有的物品数量,有两种方法可以做到这一点。但是,最有效和最简单的方法是使用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方法应该看起来像这样
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: false,
dataSource: responseJson
};
}
componentDidMount () {
fetch('https://api.myjson.com/bins/96ebw')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource:[]
});
});
}
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来完成,以便将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>
);
}
答案 1 :(得分:1)
您的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>
);
}