React Native 实例 - BBC新闻客户端

前端之家收集整理的这篇文章主要介绍了React Native 实例 - BBC新闻客户端前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

欢迎Follow我的GitHub: https://github.com/SpikeKing

关于React Native的实例,BBC新闻客户端. 通过访问BBC的公开网络接口,获取新闻内容,也可以根据类型显示. 在编写代码中,学习RN的知识,源码是使用ES6的规范编写,符合Facebook的RN代码最新规范.

主要技术

  1. 访问网络请求,过滤内容,获取数据.
  2. 显示多媒体页面,图片,视频,链接等.

本文源码的GitHub下载地址


配置项目

初始化项目WclBBCNews,修改package.json,添加依赖库.
Html解析库: htmlparser,时间处理库: moment,线性梯度库: react-native-linear-gradient,视频库: react-native-video.

  1. "dependencies": {
  2. "react": "^0.14.8","react-native": "^0.24.1","htmlparser": "^1.7.7","moment": "^2.11.1","react-native-linear-gradient": "^1.4.0","react-native-video": "^0.6.1" }

目前,React Native禁止使用-初始化项目名称,最好使用驼峰式.

初始化主模块index.ios.js,使用NavigatorIOS导航页面,首页组件Feed模块.

  1. render() {
  2. return (
  3. <NavigatorIOS style={{flex:1}} translucent={false} barTintColor={'#BB1919'} titleTextColor={'white'} tintColor={'white'} initialRoute={{ component: Feed,title: "Feed",passProps: {} }}/> ); }

渲染使用动态加载组件,StatusBar使用浅色样式.

  1. _renderScene(route,navigator) {
  2. var Component = route.component;
  3. StatusBar.setBarStyle('light-content');
  4. return (
  5. <Component {...route.props} changeNavBarHeight={this.changeNavBarHeight} navigator={navigator} route={route}/> ); }

StatusBar样式只有两种,默认default,字是黑色; 可选light-content,字是白色.


新闻列表

Feed页面,主要以列表形式,即ListView标签,显示新闻. 未加载完成时,调用页面加载提示ActivityIndicatorIOS,显示动画.

  1. render() {
  2. // 未加载完成时,调用加载页面
  3. if (!this.state.loaded) {
  4. return this._renderLoading();
  5. }
  6. // ...
  7. }
  8.  
  9. _renderLoading() {
  10. return (
  11. <View style={{flexDirection: 'row',justifyContent: 'center',flex: 1}}> <ActivityIndicatorIOS animating={this.state.isAnimating} style={{height: 80}} size="large"/> </View> ); }

加载完成后,调用ListView显示页面,renderRow渲染每一行,refreshControl加载页面的过场.

  1. return (
  2. <ListView testID={"Feed Screen"} dataSource={this.state.dataSource} renderRow={this._renderStories.bind(this)} style={{backgroundColor: '#eee'}} contentInset={{top:0, left:0,bottom: 64,right: 0}} scrollEventThrottle={200} {...this.props} refreshControl={ <RefreshControl refreshing={this.state.isRefreshing} onRefresh={this._fetchData.bind(this)} tintColor='#BB1919' title="Loading..." progressBackgroundColor="#FFFF00" />} /> );

每一行使用Story模块渲染.

  1. _renderStories(story) {
  2. return (
  3. <Story story={story} navigator={this.props.navigator}/> ); }

启动页面的时候,使用fetch方法加载数据.

  1. componentDidMount() {
  2. this._fetchData();
  3. }

通过访问BBC的网络请求,异步获取数据. 使用_filterNews过滤需要的数据,把数据设置入每一行,修改状态setState,重新渲染页面.

  1. _fetchData() {
  2. this.setState({isRefreshing: true});
  3. fetch(`http://trevor-producer-cdn.api.bbci.co.uk/content${this.props.collection || '/cps/news/world'}`)
  4. .then((response) => response.json())
  5. .then((responseData) => this._filterNews(responseData.relations))
  6. .then((newItems) => {
  7. this.setState({
  8. dataSource: this.state.dataSource.cloneWithRows(newItems),loaded: true,isRefreshing: false,isAnimating: false
  9. })
  10. }).done();
  11. }

列表项提供分类显示功能,点击类别,可以重新加载所选类型的新闻,把Feed页面再次添加至导航navigator,即页面栈.

  1. _pressedCollection(collection) {
  2. this.props.navigator.push({
  3. component: Feed,title: collection.content.name,passProps: {
  4. collection: collection.content.id,navigator: this.props.navigator
  5. }
  6. });
  7. }

点击列表项,跳转至详情页面StoryDetail.

  1. _pressedStory(story) {
  2. this.props.navigator.push({
  3. component: StoryDetail,title: this._truncateTitle(story.content.name),passProps: {story,navigator: this.props.navigator}
  4. });
  5. }

@H_216_403@新闻详情

主要是解析HTML页面,加载并显示,除了文字之外,会显示图片\视频\超链接等样式. 渲染使用动态元素,状态stateelements属性.

  1. render() {
  2. if (this.state.loading) {
  3. return (
  4. <Text>Loading</Text> ); } return this.state.elements; }

页面启动时,加载数据. 在_fetchStoryData方法中,进行处理,使用回调返回数据. 主要内容body与多媒体media通过滚动视图ScrollView的形式显示出来.

  1. componentDidMount() {
  2. this._fetchStoryData(
  3. // media表示视频或图片.
  4. (result,media) => {
  5. const rootElement = result.find(item => {
  6. return item.name === 'body';
  7. });
  8.  
  9. XMLToReactMap.createReactElementsWithXMLRoot(rootElement,media)
  10. .then(array => {
  11. var scroll = React.createElement(ScrollView,{
  12. contentInset: {top: 0,left: 0,bottom: 64,right: 0},style: {flex: 1,flexDirection: 'column',backgroundColor: 'white'},accessibilityLabel: "Story Detail"
  13. },array);
  14.  
  15. this.setState({loading: false,elements: scroll});
  16. });
  17. }
  18. );
  19. }

处理数据,使用fetch方法,分离视频与图片,还有页面,通过回调cb(callback)的处理返回数据.

  1. _fetchStoryData(cb) {
  2. // 提取数据,转换JSON格式,图片过滤,视频过滤,组合relations,解析.
  3. fetch(`http://trevor-producer-cdn.api.bbci.co.uk/content${this.props.story.content.id}`)
  4. .then((response) => response.json())
  5. .then((responseData) => {
  6. const images = responseData.relations.filter(item => {
  7. return item.primaryType === 'bbc.mobile.news.image';
  8. });
  9. const videos = responseData.relations.filter(item => {
  10. return item.primaryType === 'bbc.mobile.news.video';
  11. });
  12. const relations = {images,videos};
  13. this._parseXMLBody(responseData.body,(result) => {
  14. cb(result,relations);
  15. });
  16. }).done();
  17. }

使用Tautologistics解析dom数据与body数据. DOM,即Document Object Model,文件对象模型.

  1. _parseXMLBody(body,cb) {
  2. var handler = new Tautologistics.NodeHtmlParser.DefaultHandler(
  3. function (error,dom) {
  4. cb(dom)
  5. },{enforceEmptyTags: false,ignoreWhitespace: true});
  6.  
  7. var parser = new Tautologistics.NodeHtmlParser.Parser(handler);
  8. parser.parseComplete(body);
  9. }

XML解析类XMLToReactMap比较复杂,不做过多介绍,参考源码.


感谢我的朋友Joel Trew的实例,本文改动一些源码.

通过编写新闻类应用,学习使用网络请求和解析HTML格式的文本. 多编码多思考,不断学习,React Native是非常有意思的开发语言.

OK,that’s all! Enjoy it!


最初发布地址:
http://www.wangchenlong.org/2016/05/07/1605/071-rn-bbc-news/
欢迎Follow我的@L_403_6@,关注我的简书,CSDN,掘金. 我已委托“维权骑士”为我的文章进行维权行动. 未经授权,禁止转载,授权或合作请留言.

猜你在找的React相关文章