如何在 React 或 React Native 中重构来自 Parse(或任何数据源)的响应?
How do I refactor a response from Parse (or any data source) in React or React Native?
我正在使用 React Native 重新构建我之前在 Swift 中制作的应用程序。这是现阶段带有图钉的简单地图。它使用虚拟数据呈现,我可以从 Parse 成功查询数据,但我不知道如何正确映射它,因为我无法使用语法来检查查询是否已完成。我认为,关键在于理解 React 状态和 Javascript/JSX 语法——感谢指导。
相关代码:
var testApp = React.createClass({
mixins: [ParseReact.Mixin],
getInitialState() {
return {
mapRegion: {
latitude: 22.27,
longitude: 114.17,
latitudeDelta: 0.2,
longitudeDelta: 0.2,
},
annotations: null,
isFirstLoad: true,
};
},
componentDidMount: function() {
this.setState({isLoading: true});
},
render() {
// console.log(this.data.sites); // this works without the below
return (
<View>
<MapView
style={styles.map}
region={this.state.mapRegion || undefined}
annotations={this.state.data.sites.map(function(site) { // error
var pinObj = {};
pinObj.latitude = site.Lat;
pinObj.longitude = site.Long;
pinObj.title = site.Name;
pinObj.subtitle = site.Address;
return pinObj;
}) || undefined}
/>
</View>
);
},
observe: function(props, state) {
var siteQuery = (new Parse.Query('Site')).ascending('Name');
return state.isLoading ? {sites: siteQuery} : null;
},
});
产生错误:“无法读取未定义的 的 属性 'sites'”。这显然是因为我试图在查询返回之前遍历站点数据。我该如何修改我的语法来解决这个问题?在单独的函数中定义地图?
当然,当您渲染组件时数据可能还不可用。
ParseReact mixin /observe 的工作方式是仅在解析查询 returns 之后调用 observe 方法。所以方法的顺序是:
getInitialState()
componentDidMount()
... here parse's query starts I believe
render()
.... here some time passes
observe() // here the query returns the data
.... Parse's ParseReactMixin updates state via this.setState({data: returnedValue})
.... changed state triggers rerender
render()
Render 被调用两次 - 一次是在加载数据之前,第二次是在加载数据之后。
你应该做的是检查状态并显示一些加载状态(在我们的例子中最有可能映射一些加载指示器。例如:
render(): function {
if(this.state.isLoading) {
return <View><Map ..... (no annotations) ></Map><ActivityIndicatorIOS/></View>
} else {
return <View><Map .... (with annotations)></Map></View>
}
}
或者,您可以定义一些 "getAnnotations()" 方法,如果真实注释不可用,这些方法将 return 真实注释或虚拟(或空注释)。然后您可以将其用作
...
annotations={this.getAnnotations()}
...
并在 ActivityIndicatorIOS 上添加正确的参数组合(动画 = {this.state.isLoading} hidesWhenStoped=true}
我正在使用 React Native 重新构建我之前在 Swift 中制作的应用程序。这是现阶段带有图钉的简单地图。它使用虚拟数据呈现,我可以从 Parse 成功查询数据,但我不知道如何正确映射它,因为我无法使用语法来检查查询是否已完成。我认为,关键在于理解 React 状态和 Javascript/JSX 语法——感谢指导。
相关代码:
var testApp = React.createClass({
mixins: [ParseReact.Mixin],
getInitialState() {
return {
mapRegion: {
latitude: 22.27,
longitude: 114.17,
latitudeDelta: 0.2,
longitudeDelta: 0.2,
},
annotations: null,
isFirstLoad: true,
};
},
componentDidMount: function() {
this.setState({isLoading: true});
},
render() {
// console.log(this.data.sites); // this works without the below
return (
<View>
<MapView
style={styles.map}
region={this.state.mapRegion || undefined}
annotations={this.state.data.sites.map(function(site) { // error
var pinObj = {};
pinObj.latitude = site.Lat;
pinObj.longitude = site.Long;
pinObj.title = site.Name;
pinObj.subtitle = site.Address;
return pinObj;
}) || undefined}
/>
</View>
);
},
observe: function(props, state) {
var siteQuery = (new Parse.Query('Site')).ascending('Name');
return state.isLoading ? {sites: siteQuery} : null;
},
});
产生错误:“无法读取未定义的 的 属性 'sites'”。这显然是因为我试图在查询返回之前遍历站点数据。我该如何修改我的语法来解决这个问题?在单独的函数中定义地图?
当然,当您渲染组件时数据可能还不可用。
ParseReact mixin /observe 的工作方式是仅在解析查询 returns 之后调用 observe 方法。所以方法的顺序是:
getInitialState()
componentDidMount()
... here parse's query starts I believe
render()
.... here some time passes
observe() // here the query returns the data
.... Parse's ParseReactMixin updates state via this.setState({data: returnedValue})
.... changed state triggers rerender
render()
Render 被调用两次 - 一次是在加载数据之前,第二次是在加载数据之后。 你应该做的是检查状态并显示一些加载状态(在我们的例子中最有可能映射一些加载指示器。例如:
render(): function {
if(this.state.isLoading) {
return <View><Map ..... (no annotations) ></Map><ActivityIndicatorIOS/></View>
} else {
return <View><Map .... (with annotations)></Map></View>
}
}
或者,您可以定义一些 "getAnnotations()" 方法,如果真实注释不可用,这些方法将 return 真实注释或虚拟(或空注释)。然后您可以将其用作
...
annotations={this.getAnnotations()}
...
并在 ActivityIndicatorIOS 上添加正确的参数组合(动画 = {this.state.isLoading} hidesWhenStoped=true}