初学React Native,根据官方示例教程编写一个简单的应用Movie Fetcher,可以从电影数据库中取得最近正在上映的25部电影,并在一个ListView中展示出来。让我们开始吧
准备工作
React Native需要一些基础的配置工作,你可以参考开始使用React Native来进行。
在所有依赖的软件都已经安装完毕后,只需要输入两条命令就可以创建一个React Native工程。
-
npm install -g react-native-cli
react-native-cli是一个终端命令,它可以完成其余的设置工作。它可以通过npm安装。刚才这条命令会往你的终端安装一个叫做react-native的命令。这个安装过程你只需要进行一次。 react-native init SampleAppMovies
这个命令会初始化一个工程、下载React Native的所有源代码和依赖包,最后在SampleAppMovies/iOS/SampleAppMovies.xcodeproj
和SampleAppMovies/android/app
下分别创建一个新的XCode工程和一个grade工程。
译注:由于众所周知的网络原因,react-native命令行从npm官方源拖代码时会遇上麻烦。请先将npm仓库源替换为国内镜像:
npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global
另,执行init时切记不要在前面加上sudo(否则新项目的目录所有者会变为root而不是当前用户,导致一系列权限问题。如果你这样做了,请使用chown命令修复)。
开发
想开发iOS版本,你现在可以在XCode中打开刚刚创建的工程(SampleAppMovies/iOS/SampleAppMovies.xcodeproj),然后只要按下⌘+R就可以构建并运行。这个操作会同时打开一个用于实现动态代码加载的Node服务(React Packager)。所以每当你修改代码,你只需要在模拟器中按下 ⌘+R ,而无需重新在XCode中编译。
模拟数据
译注:本文的示例代码改用了ES6语法,可能和其他文档写法不一致。但React Native从0.18之后,新建项目默认已经采用了ES6语法,故我们推荐不熟悉ES6与ES5区别的朋友先读读这篇文章,另外还可以看看阮一峰老师的书。
在我们真正从Rotten Tomatoes(译注:一个国外的电影社区)抓取数据之前,我们先制造一些模拟数据来练一练手。在Facebook我们通常在JS文件的开头,紧跟着import语句之后声明一个常量,不过这不重要,你可以把它放在index.ios.js和index.android.js的任意位置:
var MOCKED_MOVIES_DATA = [
{title: '标题', year: '2015', posters: {thumbnail: 'http://i.imgur.com/UePbdph.jpg'}},
];
注意:如果在iOS上使用http链接的图片地址无法显示,出现ATS问题,请参见这篇说明修改。
展现一个电影
我们接下来要展现一个电影,绘制它的标题、年份、以及缩略图(译注:这个过程我们通常会叫做“渲染/render”,后面我们都会用“渲染”这个词)。渲染缩略图需要用到Image组件,所以把Image添加到对React的import列表中。
import React, {
Component,
} from 'react';
import {
AppRegistry,
Image,
StyleSheet,
Text,
View,
} from 'react-native';
然后修改一下render函数,这样我们可以把上面创建的模拟数据渲染出来。
render() {
var movie = MOCKED_MOVIES_DATA[0];
return (
<View style={styles.container}>
<Text>{movie.title}</Text>
<Text>{movie.year}</Text>
<Image source={{uri: movie.posters.thumbnail}} />
</View>
);
}
按下⌘+R
或者Reload JS
,现在你应该能看到文字"Title"和"2015",但现在Image组件没渲染任何东西,这是因为我们还没有为图片指定我们想要渲染的宽和高。这通过样式来实现。当我们修改样式的时候,我们也应该清理掉我们不再使用的样式。
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
thumbnail: {
width: 53,
height: 81,
},
});
然后把它应用到Image组件上:
<Image
source={{uri: movie.posters.thumbnail}}
style={styles.thumbnail}
/>
正常应该能够渲染出网络图片,但是!!!笔者有种严重中奖的赶脚,到最后都是这种效果(为了看Image是否存在,给它加了个背景色,去掉就啥也看不见了):
我的代码如下:
import React, { Component } from 'react';
import { AppRegistry, Image, StyleSheet, Text, View} from 'react-native';
var MOCKED_MOVIES_DATA = [ {title: 'Title', year: '2016', posters: {thumbnail:'http://i.imgur.com/UePbdph.jpg'}}];
class SampleAppMovies extends Component {
render() {
var movie = MOCKED_MOVIES_DATA[0];
return (
<View style={styles.container}>
<Text>{movie.title}</Text>
<Text>{movie.year}</Text>
<Image
source={{uri: movie.posters.thumbnail}}
style={styles.thumbnail}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
thumbnail: {
width: 53,
height: 81,
backgroundColor:'#000000'
},
// welcome: {
// fontSize: 20,
// textAlign: 'center',
// margin: 10,// },
// instructions: {
// textAlign: 'center',
// color: '#333333',
// marginBottom: 5,
// },
});
AppRegistry.registerComponent('SampleAppMovies', () => SampleAppMovies);
纯初学者求教多谢