React Native 开发豆瓣评分(八)首页开发

首页完成效果展示:

<div style="text-align:center;"> <img src="https://img2018.cnblogs.com/blog/1312841/201907/1312841-20190718135309802-1875493361.gif" /> </div>

一、开发占位图组件

在没有数据的时候使用占位图替代 items 的位置。

在 components 目录里创建 moviesItemPlaceholder.js

1import React, { Component } from 'react'; 2import { View, StyleSheet } from 'react-native'; 3import { px } from '../utils/device'; 4 5export default class MoviesItemPlaceholder extends Component { 6 render() { 7 const arr = [1, 2, 3, 4]; 8 return ( 9 <View style={styles.page}> 10 {arr.map((index) => ( 11 <View style={styles.placeholder} key={index}> 12 <View style={styles.img} /> 13 <View style={styles.title} /> 14 <View style={styles.rate} /> 15 </View> 16 ))} 17 </View> 18 ) 19 } 20} 21 22const styles = StyleSheet.create({ 23 page: { 24 flexDirection: 'row', 25 paddingLeft: px(30) 26 }, 27 placeholder: { 28 width: px(160), 29 marginRight: px(16) 30 }, 31 img: { 32 width: px(160), 33 height: px(224), 34 overflow: 'hidden', 35 borderRadius: px(8), 36 backgroundColor: '#f8f8f8' 37 }, 38 title: { 39 marginTop: px(20), 40 backgroundColor: '#f8f8f8', 41 height: px(30), 42 width: px(130), 43 overflow: 'hidden', 44 borderRadius: px(8) 45 }, 46 rate: { 47 marginTop: px(16), 48 backgroundColor: '#f8f8f8', 49 height: px(24), 50 width: px(130), 51 overflow: 'hidden', 52 borderRadius: px(8) 53 } 54});

二、首頁数据请求

使用 postman 之类的工具可以看到,首页接口返回的数据字段大致一样,数据均在 subject_collection_items 字段里,可以疯转一个方法量来请求数据。

1var items = ['showing', 'hot', 'tv', 'variety', 'book', 'music']; 2items.forEach(type => { 3 this.getList(type); 4}); 5getList = (type) => { 6 ajax(type, { 7 start: 0, 8 count: 9 9 }).then(value => { 10 let state = {} 11 state[type] = value.subject_collection_items; 12 this.setState(state); 13 }) 14 }

首页页面展示

纵向滑动,使用 ScrollView 组件;横向滑动,使用 FlatList 组件,FlatList 组件的 ListEmptyComponent 表示没有数据时显示的组件,在这里放置占位图组件;

1import React from "react"; 2import { View, Text, StatusBar, StyleSheet, ScrollView, FlatList, TouchableWithoutFeedback } from "react-native"; 3import { connect } from 'react-redux'; 4import ajax from "../utils/ajax"; 5import Header from '../components/header'; 6import ItemsHeader from '../components/itemsHeader'; 7import MoviesItem from '../components/moviesItem'; 8import MoviesItemPlaceholder from '../components/moviesItemPlaceholder'; 9import Icon from 'react-native-vector-icons/AntDesign'; 10import { px } from "../utils/device"; 11 12class Home extends React.Component { 13 constructor(props) { 14 super(props); 15 this.state = { 16 showing: [], 17 hot: [], 18 tv: [], 19 variety: [], 20 book: [], 21 music: [], 22 } 23 var items = ['showing', 'hot', 'tv', 'variety', 'book', 'music']; 24 items.forEach(type => { 25 this.getList(type); 26 }); 27 } 28 getList = (type) => { 29 ajax(type, { 30 start: 0, 31 count: 9 32 }).then(value => { 33 let state = {} 34 state[type] = value.subject_collection_items; 35 this.setState(state); 36 }) 37 } 38 render() { 39 const { dispatch, value, navigation } = this.props; 40 const { showing, hot, tv, variety, book, music } = this.state; 41 const sections = [ 42 { title: '影院热映', data: showing, type: 'showing' }, 43 { title: '豆瓣热门', data: hot, type: 'hot' }, 44 { title: '近期热门剧集', data: tv, type: 'tv' }, 45 { title: '近期热门综艺节目', data: variety, type: 'variety' }, 46 { title: '畅销图书', data: book, type: 'book' }, 47 { title: '热门单曲榜', data: music, type: 'music' } 48 ] 49 return ( 50 <View style={styles.page}> 51 <Header showBack={false} title='豆瓣评分' backgroundColor='#00b600' color='#fff' /> 52 <ScrollView> 53 <View style={styles.search}> 54 <TouchableWithoutFeedback onPress={() => alert('search')}> 55 <View style={styles.searchView}> 56 <Icon name='search1' size={px(30)} color='#ccc' /> 57 <Text style={styles.searchText}>搜索</Text> 58 </View> 59 </TouchableWithoutFeedback> 60 </View> 61 {sections.map((list, index) => ( 62 <View key={index} style={styles.list}> 63 <ItemsHeader title={list.title} onPress={() => navigation.push('List', { data: list })} /> 64 <FlatList 65 horizontal={true} 66 data={list.data} 67 keyExtractor={(item, index) => 'item' + index} 68 ListEmptyComponent={() => <MoviesItemPlaceholder />} 69 renderItem={({ item, index }) => ( 70 <View style={{ marginRight: index !== showing.length - 1 ? px(16) : px(30), marginLeft: index === 0 ? px(30) : 0 }}> 71 <MoviesItem data={item} /> 72 </View> 73 )} 74 /> 75 </View> 76 ))} 77 </ScrollView> 78 </View> 79 ); 80 } 81} 82 83const select = (store) => { 84 return { 85 value: store.num.value, 86 } 87} 88 89export default connect(select)(Home); 90 91const styles = StyleSheet.create({ 92 page: { 93 flex: 1, 94 backgroundColor: '#fff' 95 }, 96 search: { 97 backgroundColor: '#00b600', 98 height: px(80), 99 alignItems: 'center', 100 justifyContent: 'center' 101 }, 102 searchView: { 103 height: px(50), 104 width: px(710), 105 borderRadius: px(8), 106 backgroundColor: '#fff', 107 flexDirection: 'row', 108 justifyContent: 'center', 109 alignItems: 'center' 110 }, 111 searchText: { 112 fontSize: px(26), 113 color: '#ccc', 114 marginLeft: px(6) 115 }, 116 list: { 117 marginBottom: px(30) 118 } 119});

四、缓存列表数据

当处于弱网环境时,打开应用,可能会显示很久的占位图,此时我们可以将列表数据缓存至本地,每次进入应用先展示本地缓存的数据,然后请求数据,替换本地数据。

此时,就可以使用 redux 了。

编译 reducer

为了目录整清晰点(让 redux 相关的代码文件都存储于 store 目录下),将 src 目录下的 reducer 目录移动到 store 目录下,并在 reducer 目录创建 list.js。

1const initList = { 2 showing: [], 3 hot: [], 4 tv: [], 5 variety: [], 6 book: [], 7 music: [] 8} 9 10const setListState = (state = initList, action) => { 11 switch (action.type) { 12 case 'showing': 13 return { 14 ...state, 15 showing: action.data 16 } 17 case 'hot': 18 return { 19 ...state, 20 hot: action.data 21 } 22 case 'tv': 23 return { 24 ...state, 25 tv: action.data 26 } 27 case 'variety': 28 return { 29 ...state, 30 showing: action.data 31 } 32 case 'book': 33 return { 34 ...state, 35 book: action.data 36 } 37 case 'music': 38 return { 39 ...state, 40 music: action.data 41 } 42 default: 43 return state; 44 } 45} 46 47export default setListState;

在 reducer 的 index.js 中导入 setListState;

1... 2import setListState from './list'; 3... 4export default combineReducers({ 5 ... 6 list: setListState 7 ... 8});

修改 store/index.js 的路径引入

import reducer from './reducer';

编辑 action

将之前src下的 action 目录删除,在 store 目录下创建 action.js。

1export function login(data) { 2 return { 3 type: 'login', 4 data 5 } 6} 7 8export function logout(data) { 9 return { 10 type: 'logout', 11 data 12 } 13} 14 15// set 首页列表数据 16export function setShowing(data) { 17 return { 18 type: 'showing', 19 data 20 } 21} 22export function setHot(data) { 23 return { 24 type: 'hot', 25 data 26 } 27} 28export function setTv(data) { 29 return { 30 type: 'tv', 31 data 32 } 33} 34export function setVariety(data) { 35 return { 36 type: 'variety', 37 data 38 } 39} 40export function setBook(data) { 41 return { 42 type: 'book', 43 data 44 } 45} 46export function setMusic(data) { 47 return { 48 type: 'music', 49 data 50 } 51}

编辑首页

导入修改 store 的方法:

import { setShowing, setHot, setTv, setVariety, setBook, setMusic } from '../store/action';

页面获取 store 存储的数据:

1const select = (store) => { 2 return { 3 showing: store.list.showing, 4 hot: store.list.hot, 5 tv: store.list.tv, 6 variety: store.list.variety, 7 book: store.list.book, 8 music: store.list.music 9 } 10} 11export default connect(select)(Home);

页面获取数据时,改变 store 里的数据

由于需要 save 数据,所以前面创建的 getList 和传入的 items 需要做一些改变:

1... 2var items = [ 3 { type: 'showing', save: setShowing }, 4 { type: 'hot', save: setHot }, 5 { type: 'tv', save: setTv }, 6 { type: 'variety', save: setVariety }, 7 { type: 'book', save: setBook }, 8 { type: 'music', save: setmusic }, 9] 10items.forEach(item => { 11 this.getList(item); 12}); 13... 14getList = (item) => { 15 ajax(item.type, { 16 start: 0, 17 count: 9 18 }).then(value => { 19 this.props.dispatch(item.save(value.subject_collection_items)); 20 }) 21 }

修改 render 里的获取数据方式:

1render(){ 2 const { dispatch, value, navigation, showing, hot, tv, variety, book, music } = this.props; 3 ... 4}

至此,首页算是开发完了。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )