本文中我们将创建一个简单的电影应用,这个应用将从Rotten Tomatoes网站抓取目前正在上映的最新的25部电影,并将它们展示在一个ListView中。
一、伪造数据
在我们开始编写代码从Rotten Tomatoes网站抓取数据之前,我们先来伪造一些数据,以便我们可以马上体验一下React Native。我们一般会在JS文件的顶部声明常量,并在后面使用。在index.ios.js中添加以下代码:
var MOCKED_MOVIES_DATA = [ {title: 'Title', year: '2015', posters: {thumbnail: 'http://i.imgur.com/UePbdph.jpg'}}, ];
二、渲染一部电影
我们会渲染电影的标题、年份以及海报缩略图。由于缩略图在React Native中是一个Image组件,所以我们需要将Image组件加到React的依赖项中。
var { AppRegistry, Image, StyleSheet, Text, View, } = React;
现在我们来修改render函数,以便我们可以渲染上面的模拟数据。
render: function() { 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> ); }
同时我们还需要修改styles,用来将样式应用到相应的组件上。
var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, thumbnail: { width: 53, height: 81, }, });
按下cmd+R,此时的电影标题、年份以及海报缩略图已经渲染出来了。
三、修改样式,将文字放在图片的右侧
接下来,我们把文字放在图片的右侧,同时让标题字体大一些并居中显示。
修改render函数,添加另一个View,这是为了让我们的组件在最外层的组件中垂直居中显示。
render: function() { var movie = MOCKED_MOVIES_DATA[0]; return ( <View style={styles.container}> <Image source={{uri: movie.posters.thumbnail}} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title}>{movie.title}</Text> <Text style={styles.year}>{movie.year}</Text> </View> </View> ); }
同时我们还需要修改styles,用来将样式应用到相应的组件上。
var styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, thumbnail: { width: 53, height: 81, }, rightContainer: { flex: 1, }, title: { fontSize: 20, marginBottom: 8, textAlign: 'center', }, year: { textAlign: 'center', }, });
按下cmd+R来查看更新之后的视图。
四、抓取真实数据
将下面的常量放在文件的顶部,用来创建一个请求数据使用的REQUEST_URL:
var API_KEY = '7waqfqbprs7pajbz28mqf6vz'; var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json'; var PAGE_SIZE = 25; var PARAMS = '?apikey=' + API_KEY + '&page_limit=' + PAGE_SIZE; var REQUEST_URL = API_URL + PARAMS;
为我们的应用添加初始状态,这样我们可以通过检查this.state.movies === null来确定电影数据有没有被加载。当电影数据返回时,我们可以通过this.setState({movies: moviesData})来设置数据。
将下面的代码添加到render函数之前:
getInitialState: function() { return { movies: null, }; },
我们想要在组件完成加载后发送请求,componentDidMount是React组件中的一个函数,它只会在组件加载完成后被调用一次。
componentDidMount: function() { this.fetchData(); },
接下来添加组件中会用到的fetchData函数,这个函数将负责处理数据的抓取。你需要做的仅仅是在promise完成解析后调用this.setState({movies: data})。因为setState会触发重新渲染,而此时render函数会注意到this.state.movies不再是null。
注意一定要在promise链的最后调用done(),否则错误信息可能会被忽略。
fetchData: function() { fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) => { this.setState({ movies: responseData.movies, }); }) .done(); },
现在修改render函数,如果电影数据还没有返回的话,就渲染一个loading视图,否则将渲染第一部电影。
render: function() { if (!this.state.movies) { return this.renderLoadingView(); } var movie = this.state.movies[0]; return this.renderMovie(movie); }, renderLoadingView: function() { return ( <View style={styles.container}> <Text> Loading movies... </Text> </View> ); }, renderMovie: function(movie) { return ( <View style={styles.container}> <Image source={{uri: movie.posters.thumbnail}} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title}>{movie.title}</Text> <Text style={styles.year}>{movie.year}</Text> </View> </View> ); },
按下cmd+R,首先会看到loading页面
电影数据返回后,就会渲染第一部从Rotten Tomatoes获取过来的电影。
五、显示完整的电影列表
现在我们来修改应用,将所有的数据渲染在一个ListView组件中,而不是只渲染一部电影。
这里使用ListView是因为ListView会自动渲染视线之内的视图,而那些在屏幕之外的视图会被暂时移除。
这里既然用到了ListView,我们就需要将ListView组件加到React的依赖项中。
var { AppRegistry, Image, ListView, StyleSheet, Text, View, } = React;
接下来修改render函数,一旦数据返回就可以在ListView里面渲染数据:
render: function() { if (!this.state.loaded) { return this.renderLoadingView(); } return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderMovie} style={styles.listView} /> ); },
DataSource是ListView的一个接口,作用是决定哪些行会改变。
接下来,我们需要在getInitialState的返回对象上添加一个空的dataSource,我们不能再使用this.state.movies防止数据被存储两次。我们可以使用this.state.loaded来判断数据抓取是否结束。
getInitialState: function() { return { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }), loaded: false, }; },
我们还需要修改fetchData来更新state:
fetchData: function() { fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) => { this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData.movies), loaded: true, }); }) .done(); },
最后,我们在styles中为ListView组件添加样式:
listView: { paddingTop: 20, backgroundColor: '#F5FCFF', },
下面是最终的效果图:
六、本文最终完整的源码
'use strict'; var React = require('react-native'); var API_KEY = '7waqfqbprs7pajbz28mqf6vz'; var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json'; var PAGE_SIZE = 25; var PARAMS = '?apikey=' + API_KEY + '&page_limit=' + PAGE_SIZE; var REQUEST_URL = API_URL + PARAMS; var { AppRegistry, Image, ListView, StyleSheet, Text, View, } = React; var Movie = React.createClass({ getInitialState: function() { return { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }), loaded: false, }; }, componentDidMount: function() { this.fetchData(); }, fetchData: function() { fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) => { this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData.movies), loaded: true, }); }) .done(); }, render: function() { if (!this.state.loaded) { return this.renderLoadingView(); } return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderMovie} style={styles.listView} /> ); }, renderLoadingView: function() { return ( <View style={styles.container}> <Text> Loading movies... </Text> </View> ); }, renderMovie: function(movie) { return ( <View style={styles.container}> <Image source={{uri: movie.posters.thumbnail}} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title}>{movie.title}</Text> <Text style={styles.year}>{movie.year}</Text> </View> </View> ); }, }); var styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, thumbnail: { width: 53, height: 81, }, rightContainer: { flex: 1, }, title: { fontSize: 20, marginBottom: 8, textAlign: 'center', }, year: { textAlign: 'center', }, listView: { paddingTop: 20, backgroundColor: '#F5FCFF', }, }); AppRegistry.registerComponent('Movie', () => Movie);
相关推荐
总结来说,React Native Page 是一个适用于React Native开发的分页组件,它简化了在移动应用中实现分页功能的过程,让开发者能够更加专注于业务逻辑和用户体验。通过熟练掌握和运用这个组件,可以提高开发效率,为...
1. **React Native基础知识**:React Native是Facebook推出的一个开源框架,它允许开发者使用JavaScript和React来开发原生移动应用。React是Facebook的UI库,采用组件化思想,而React Native则是将其扩展到移动平台...
在这个“用React Native开发的一个简单跑马灯抽奖demo”项目中,我们看到了React Native在创建动态、交互式用户界面方面的应用。 首先,让我们深入了解一下React Navigation。React Navigation是一个流行的导航解决...
React Native Debugger是一款强大的开发工具,特别为在macOS平台上进行React和React Native应用的可视化调试而设计。它提供了丰富的功能,使开发者能够更有效地检查、调试和优化代码,尤其是在处理复杂的Redux状态...
在本文中,我们将深入探讨如何使用React Native和Exponent来构建一个可展开的列表集合组件。React Native是一种流行的JavaScript框架,用于开发原生移动应用程序,而Exponent则是一个平台,可以简化React Native应用...
React Native滑动组件(react-native-swipeable)是基于此框架的一个扩展库,它提供了一种简单的方式来实现滑动相关的交互,如卡片滑动删除、列表项的左右滑动等常见操作。 滑动组件的核心功能包括: 1. **双向...
在React Native中构建一个具有折叠效果的二级列表,并在点击时改变字体颜色,涉及到的关键技术主要包括React Native的基础组件使用、ListView的实现以及事件处理。React Native是Facebook推出的一个开源框架,它允许...
React-Native是由Facebook开发的一个开源框架,它允许开发者使用JavaScript和React来构建原生移动应用。React是Facebook推出的用于构建用户界面的JavaScript库,它的核心理念是组件化,通过组合多个小而独立的组件来...
React Native 是一个由...总的来说,“快速搭建React Native项目的一个starter”是一个宝贵的资源,可以帮助开发者高效地开始他们的React Native之旅,利用已有的配置和最佳实践,快速构建出功能丰富的移动应用。
使用`react-native init`命令初始化一个新的React Native项目,这会为你生成项目模板。了解项目目录结构,包括`src`目录中的`App.js`,这是应用的入口点。 4. **组件化编程** 学习如何定义和使用组件,如状态...
ReactNative项目Demo是一个基于ReactNative框架构建的针对iPad设备的应用示例。ReactNative是由Facebook开发的开源库,它允许开发者使用JavaScript和React编程理念来构建原生移动应用程序。这个项目Demo旨在提供一个...
这个“RNExampleApp-master”压缩包文件很可能包含了一个完整的React Native项目实例,让我们来深入探讨一下相关的关键知识点。 1. **React Native基础**:React Native的核心理念是“Learn once, write anywhere”...
本教程将指导你如何为你的React Native应用添加一个气泡菜单效果。 首先,你需要了解React Native的基本概念。React Native是由Facebook开发的开源框架,它允许使用JavaScript和React来构建原生移动应用。通过JSX...
1. **React Native简介**:React Native是Facebook开源的一个框架,它允许开发者使用JavaScript和React组件库来构建原生的iOS和Android应用程序。它的核心理念是“Learn once, write anywhere”,即学习一次,到处...
React Native 混编构建的App是现代移动应用开发中的一个重要技术实践,它结合了JavaScript的灵活性和原生平台的强大性能。React Native是由Facebook开发的一个开源框架,允许开发者使用JavaScript和React库来创建高...
React Native 是一个流行的开源框架,它允许开发者使用JavaScript来构建原生的移动应用程序。这个框架的优势在于其跨平台的能力,可以同时为iOS和Android提供一致的用户体验。在React Native中,组件是构建用户界面...
2. **创建项目**:使用`react-native init`命令创建一个新的React Native项目,然后根据UWP要求进行调整。 3. **集成UWP**:将项目配置为支持UWP平台,添加必要的依赖,并解决可能出现的平台特定问题。 4. **开发和...
在“使用react native开发的一个one客户端”这个项目中,我们可以理解为开发者已经利用React Native技术创建了一个名为“ONE”的移动应用客户端。这个客户端可能是针对某种特定服务或平台,如在线阅读、学习资源、...
React Native 是一个由Facebook开发的开源框架,它允许开发者使用JavaScript和React的组件化思想来构建原生的iOS和Android应用程序。在这个特定的场景中,我们讨论的是一个React Native的自定义键盘插件,这对于创建...