跟我学用REACT NATIVE构建原生应用(四)
本文案例、代码及主要内容基于知乎前端专栏翻译的文章《深入浅出React Native:使用JavaScript构建原生应用》《Introducing React Native: Building Apps with JavaScript》而写。
在原文的基础上做了一些校对,并增加了android得环境安装和调试的内容。
由我书写的注释将会显示左边这个紫色竖线(#523f6d),而原文的注释为蓝色的(#559bce)。
内容传送门
一、《深入浅出R跟我学用React Native构建原生应用(一)
二、《深入浅出R跟我学用React Native构建原生应用(二)
三、《深入浅出R跟我学用React Native构建原生应用(三)
四、《深入浅出R跟我学用React Native构建原生应用(四)
五、《深入浅出R跟我学用React Native构建原生应用(五)
六、《深入浅出R跟我学用React Native构建原生应用(六)
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:kmokidd
链接:http://zhuanlan.zhihu.com/FrontendMagazine/19996445
来源:知乎
执行 API 请求
还是 SearchPage.js 文件中,更新构造器中的初始 state 添加一个message 变量:
this.state = { searchString: "london", isLoading: false, message: "" };在 render 内部,将下面的代码添加到 UI 的底部:
<Text style={styles.description}>{this.state.message}</Text>你需要使用这个为用户展示多种信息。
在 SearchPage 类内部,将以下代码添加到 _executeQuery() 底部:
fetch(query)
.then((response) => response.json())
.then((json) => this._handleResponse(json.response))
.catch((error) =>
this.setState({
isLoading: false,
message: "Something bad happened " + error,
}),
);这里使用了 fetch 函数,它是 Web API 的一部分。和 XMLHttpRequest 相比,它提供了更加先进的 API。异步响应会返回一个 promise,成功的话会转化 JSON 并且为它提供了一个你将要添加的方法。
最后一步是将下面的函数添加到 SearchPage:
_handleResponse(response) { this.setState({ isLoading: false , message: '' }); if (response.application_response_code.substr(0, 1) === '1') { console.log('Properties found: ' + response.listings.length); } else { this.setState({ message: 'Location not recognized; please try again.'}); }}如果查询成功,这个方法会清除掉正在加载标识并且记录下查询到属性的个数。
注意:Nestoria 有很多种返回码具备潜在的用途。比如,202 和 200 会返回最佳位置列表。当你创建完一个应用,为什么不处理一下这些,可以为用户呈现一个可选列表。
保存项目,然后在模拟器中按下 Cmd+R,尝试搜索 ‘london’;你会在日志信息中看到 20 properties were found。然后随便尝试搜索一个不存在的位置,比如 ‘narnia’,你会得到下面的问候语。
是时候看一下这20个房屋所对应的真实的地方,比如伦敦!
结果显示
创建一个新的文件,命名为 SearchResults.js,然后加上下面这段代码:
"use strict";你肯定注意到啦,这里用到了 require 语句将 react-native 模块引入其中,还有一个重构赋值语句。
接着就是加入搜索结果的组件:
class SearchResults extends Component {
constructor(props) { super(props); var dataSource = new ListView.DataSource( {rowHasChanged: (r1, r2) => r1.guid !== r2.guid}); this.state = { dataSource: dataSource.cloneWithRows(this.props.listings) }; }
renderRow(rowData, sectionID, rowID) { return ( <TouchableHighlight underlayColor='#dddddd'> <View> <Text>{rowData.title}</Text> </View> </TouchableHighlight> ); }
render() { return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderRow.bind(this)}/> ); }上述的代码里用到了一个特定的组件 – ListView – 它能将数据一行行地呈现出来,并放置在一个可滚动的容器内,和 UITableView 很相似。通过 ListView.DataSource 将 ListView 的数据引入,还有一个函数来显示每一行UI。
在构建数据源的同时,你还需要一个函数用来比较每两行之间是否重复。 为了确认列表数据的变化,在 reconciliation 过程中ListView 就会使用到这个函数。在这个实例中,由 Nestoria API 返回的房屋数据都有一个guid 属性,它就是用来测试数据变化的。
现在将模块导出的代码添加至文件末尾:
module.exports = SearchResults;将下面这段代码加到 SearchPage.js 较前的位置,不过要在 require 语句的后面哦:
var SearchResults = require("./SearchResults");这样我们就能在 SearchPage 类中使用刚刚加上的 SearchResults 类。
还要把 _handleResponse 方法中的 console.log 语句改成下面这样:
this.props.navigator.push({
title: "Results",
component: SearchResults,
passProps: { listings: response.listings },
});SearchResults 组件通过上面的代码传入列表里。在这里用的是 push方法确保搜索结果全部推进导航栈中,这样你就可以通过 ‘Back’ 按钮返回到根页面。
回到模拟器,按下 Cmd+R 刷新页面,然后试试看我们的搜索。估计你会得到类似下面这样的结果:
耶!你的搜索实现了呢,不过这搜索结果页面的颜值也太低了,不要担心,接下来给它化化妆。

