概述
通过上一篇我们已经通过命令行工具构建了第一个 React Native 应用,并在 iOS 设备中成功运行,熟悉了工程的文件代码组织结构。我们将继续使用该工程来开发一个天气应用,以此初步建立对 StyleSheet、 flexbox、 用户输入、组件添加、网络访问 等概念的理解。
创建 WeatherMain.js 并移动默认组件代码
WeatherMain.js
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View
} from 'react-native';
export default class WeatherMain extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to Hello RN Weather !
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});精简
index.ios.js和index.ios.js
import { AppRegistry } from 'react-native'
import WeatherMain from './WeatherMain'
AppRegistry.registerComponent('HelloRNWeather', () => WeatherMain);更改
AppDelegate中根视图组件moduleName
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"HelloRNWeather"
initialProperties:nil
launchOptions:launchOptions];此时,确保项目重新启动可正常运行。
处理用户输入
添加一个输入框,以便用户可通过输入邮编来获取对应地区的天气
在
render函数前添加一段处理生命周期的代码
constructor(props) {
super(props)
this.state = {
zip: ''
}
}修改显示内容为邮编
<Text style={styles.welcome}>
地区邮编: {this.state.zip}
</Text>添加
TextInput输入框组件,并监听输入事件
<TextInput style={styles.input} onSubmitEditing={(event) => this._handleInputTextDidChanged(event)}/>在
styles中添加新的input样式
input: {
fontSize: 20,
borderWidth: 3,
height: 44,
}添加事件监听回调函数
_handleInputTextDidChanged(event) {
this.setState({zip: event.nativeEvent.text});
}记得更新导入语句
import {
...
TextInput,
...
} from 'react-native';在 iOS 模拟器运行项目,现在可以成功显示输入的内容了

展现数据
mock 一些天气数据
constructor(props) {
super(props);
this.state = {
zip: '',
forecast: {
main: 'Snow',
description: 'very cold',
temp: 3
}
}
}创建
Forecast.js作为天气预报组件
import React, {Component} from 'react'
import {
StyleSheet,
Text,
View,
} from 'react-native'
export default class Forecast extends Component {
render() {
return (
<View>
<Text style={styles.bigText}>
{this.props.main}
</Text>
<Text style={styles.mainText}>
{this.props.description}
</Text>
<Text style={styles.bigText}>
{this.props.temp} ℃
</Text>
</View>
)
}
}
const styles = StyleSheet.create({
bigText: {
flex: 2,
fontSize: 20,
textAlign: 'center',
margin: 10,
color: '#374256'
},
mainText: {
flex: 1,
fontSize: 16,
textAlign: 'center',
color: '#374256'
}
})将
Forecast组件添加到WeatherMain
import Forecast from './Forecast' // 导入 Forecast
<View style={styles.container}>
......
<Forecast main={this.state.forecast.main} description={this.state.forecast.description} temp={this.state.forecast.temp}/>
......
</View>添加完成后,iOS 模拟器 Command + R 即可看到之前mock的数据展现出来了,至于美观上的问题,接下来专门摸索样式布局的时候再来慢慢解决。

添加背景图片
将资源文件放入工程目录
导入
Image组件
import {
...
Image,
...
} from 'react-native';将
Image组件作为容器使用添加到视图中
<Image source={require("./background.jpg")} resizeMode='cover' style={styles.background}>
<View style={styles.overlay}>
<Text style={styles.welcome}>
地区邮编: {this.state.zip}
</Text>
<TextInput style={styles.input} onSubmitEditing={(event) => this._handleInputTextDidChanged(event)}/>
<Forecast main={this.state.forecast.main} description={this.state.forecast.description} temp={this.state.forecast.temp}/>
</View>
</Image>刷新即可看到添加的背景图片了,当然了,仍然还是丑,后面我们再慢慢来解决样式布局问题,感觉前端的布局确实和 AutoLayout 很不一样啊~ /无奈摊手
获取网络数据
接下来,我们将尝试通过网络访问来用真实数据来替换之前的 mock 数据。
React Native 中的
fetch接口基于Promise语法风格
fetch('http://wthrcdn.etouch.cn/weather_mini?citykey=101010100')
.then((response) => response.json())
.then((responseJSON) => {
// handle Response
})
.catch((error) => {
console.warn(error);
})在
render中更新渲染逻辑
render() {
var content = null;
if (this.state.forecast !== null) {
content = <Forecast main={this.state.forecast.main} description={this.state.forecast.description} temp={this.state.forecast.temp}/>;
}
......
}使用网络访问替代 mock 数据
this.state = {
zip: '',
forecast: null
};
fetch('http://wthrcdn.etouch.cn/weather_mini?citykey=101010100')
.then((res) => {
return res.json()
})
.then((responseJSON) => {
this.setState({
forecast: {
main: responseJSON.data.forecast[0].type,
description: responseJSON.data.ganmao,
temp: responseJSON.data.wendu,
}
});
})
.catch((error) => {
console.warn(error);
})刷新就能看到北京的真实天气了

== 若出现网络错误,是因为苹果 iOS 9 起不再支持http协议,需要对特定域名进行额外处理。 ==

总结
这样下来,我们就对 StyleSheet、 flexbox、 用户输入、组件添加、网络访问 等概念都有基本的认识,也完成了一个能显示实时天气的小应用了。不过它现在还很简陋、也不美观,接下来我们将在进一步认识移动应用组件后再对样式布局进行优化。