react-native之上拉加载,下拉刷新组件封装
来源:互联网 发布:如何在php中定义常量 编辑:程序博客网 时间:2024/06/07 00:34
react-native 自定义封装刷新组件
几个月没写博客了,最近一直在写react 和react-native,前几天刚发了一版基于react-native混合开发的App,这几天赶快总结下。
写过java的同学,再去学习react和react-native就会比较容易上手,并且会有一种似曾相识的感觉,不错,今天我要总结的刷新功能就和Android原生的实现很类似,在Android原生当中,可以说是家喻户晓了,在react-native中实现也是一样的简单,在rn的升级中,FlatList是listView的升级版,就好比如RecyclerView是listView的升级版一样。OK, 废话不多话说。
目录
1.FlatList常用的属性方法
2.封装一个上拉加载,下拉刷新的组件
1.FlatList常用的属性方法
- data: ?Array 为了简化起见,data属性目前只支持普通数组。
- renderItem: (info: {item: ItemT, index: number}) => ?React.Element 根据行数据data渲染每一行的组件
- onRefresh?: ?() => void 如果设置了此选项,则会在列表头部添加一个标准的RefreshControl控件,以便实现“下拉刷新”的功能。同时你需要正确设置refreshing属性。
- refreshing?: ?boolean 在等待加载新数据时将此属性设为true,列表就会显示出一个正在加载的符号。
- onEndReachedThreshold?: ?number 决定当距离内容最底部还有多远时触发onEndReached回调。注意此参数是一个比值而非像素单位。比如,0.5表示距离内容最底部的距离为当前列表可见长度的一半时触发。
- onEndReached?: ?(info: {distanceFromEnd: number}) => void 当列表被滚动到距离内容最底部不足onEndReachedThreshold的距离时调用。
- ItemSeparatorComponent?: ?ReactClass 行与行之间的分隔线组件。不会出现在第一行之前和最后一行之后。
- keyExtractor: (item: ItemT, index: number) => string 此函数用于为给定的item生成一个不重复的key。Key的作用是使React能够区分同类元素的不同个体,以便在刷新时能够确定其变化的位置,减少重新渲染的开销。若不指定此函数,则默认抽取item.key作为key值。若item.key也不存在,则使用数组下标。
- ListHeaderComponent?: ?ReactClass 头部组件
- ListFooterComponent?: ?ReactClass 尾部组件
- ListEmptyComponent?: ?ReactClass | React.Element 列表为空时渲染该组件。可以是React Component, 也可以是一个render函数, 或者渲染好的element。
extraData?: any 如果有除data以外的数据用在列表中(不论是用在renderItem还是Header或者Footer中),请在此属性中指定。同时此数据在修改时也需要先修改其引用地址(比如先复制到一个新的Object或者数组中),然后再修改其值,否则界面很可能不会刷新。
注:当然还有其他的属性方法,请自行查阅文档FlatList
2.封装一个上拉加载,下拉刷新的组件
- 先定义一些propTypes,利于组件的扩展使用
static propTypes = { renderItem: PropTypes.func.isRequired, /* 渲染行的方法 */ ItemSeparatorComponent: PropTypes.func, /* 渲染行间隔的方法 */ keyExtractor: PropTypes.func, /* 返回每行key的方法 */ ListFooterComponent: PropTypes.func, /* 渲染列表底部的方法 */ ListHeaderComponent: PropTypes.func, /* 渲染列表头部的方法 */ listUrl: PropTypes.string.isRequired, /* 获取列表的url */ fetchMethod: PropTypes.string, /* 获取列表的请求方式(默认为get) */ fetchParams: PropTypes.object, /* 获取列表的请求参数 */ pageSize: PropTypes.number, /* 每页行数(默认20条) */ formatData: PropTypes.func, /* 返回列表数组的方法 */ _ref: PropTypes.func, /* 获取组件实例属性 */ auto: PropTypes.bool, /* 是否在加载时自动查询(默认自动) */ showFooterBoo: PropTypes.bool, /* 是否显示脚 */ ref: PropTypes.func, /* 获取组件实例 */ };
2.初始化当前状态state
constructor(props) { super(props); this._fetchUrl = props.listUrl; this._fetchParams = props.fetchParams; this.state = { list: [], /* 列表数据 */ pageNum: 1, /* 当前页数 */ count: 0, /* 总条数 */ refreshing: false, /* 是否正在加载 */ isEnd: false, /* 是否加载完 */ isNotList: false, /* 是否未查询到数据 */ isError: false, /* 是否查询失败 */ } }
3.FlatList组件属性封装
- 渲染前准备
const { list, refreshing } = this.state; const { renderItem, ItemSeparatorComponent, keyExtractor = (...arg) => arg[1], ListHeaderComponent, extraData = {}, showFooterBoo, } = this.props;
- FlatList封装
<FlatList data={list} renderItem={renderItem} onRefresh={this.onRefresh} refreshing={refreshing} onEndReachedThreshold={0.2} onEndReached={this.onEndReached} ItemSeparatorComponent={ItemSeparatorComponent} keyExtractor={keyExtractor} ListHeaderComponent={this.renderListHeader} ListFooterComponent={showFooterBoo ? this.renderListFooter : null} ListEmptyComponent={this.renderListEmpty} ref={ref => this._listRef = ref} extraData={extraData} />
4.data={list} 中list数据来源于引用组件处的属性
5.renderItem={renderItem} 中renderItem来源于引用组件的Item布局属性
6.onRefresh={this.onRefresh} 下拉刷新布局如下:
/** * 下拉刷新 * @return {void} */ onRefresh = () => { this.setState({ isEnd: false, }, () => { this.getList(); }); }
/** * 获取列表 * @return {void} */ getList = (isRefresh = true) => { const { $fetch, fetchMethod = 'get', pageSize = 20, formatData = ({data}) => ({ list: data.records, count: data.total, }), fetchCatch = () => {}, } = this.props; const { list, pageNum, refreshing, isEnd } = this.state; if((refreshing || isEnd) && !isRefresh) return; const fetchPageNum = isRefresh ? 1 : pageNum; let fetchPromise; if(fetchMethod.toLowerCase() === 'get') { fetchPromise = $fetch.get(this._fetchUrl, { size: pageSize, current: fetchPageNum, ...this._fetchParams, }); } else if(fetchMethod.toLowerCase() === 'post') { fetchPromise = $fetch.post(`${this._fetchUrl}`, { ...this._fetchParams, }); } else { throw new Error('method type error! only "get" or "post"'); } this.setState({refreshing: true}); fetchPromise.then(data => { console.log(data); if(!data.success) { this.setState({ isError: true }); return; } const listData = formatData(data); const currentList = isRefresh ? listData.list : list.concat(listData.list); /* 判断是否查询到数据 */ if(fetchPageNum === 1 && listData.list.length === 0){ this.setState({ isNotList: true }); } else { this.setState({ isNotList: false }); } /* 如果有数据则添加到列表中 */ if(listData.list.length) { this.setState({ list: currentList, pageNum: fetchPageNum + 1, }); } if(currentList.length >= listData.count) { this.setState({ isEnd: true }); } this.setState({ count: listData.count, }); }).catch(err => { console.log(err.response); if(!data.success) { this.setState({ isError: true }); } fetchCatch(err); }).finally(() => { this.setState({refreshing: false}); }); }
注:get与post可以根据自己的具体需求进行优化,其中网络请求使用的fetch。
7.refreshing={refreshing} 中refreshing布尔值,是用来判断当前是否是出于刷新状态的,当处于请求数据的刷新状态时置为true。
8.onEndReachedThreshold={0.2} 当滑动比例为0.2时触发onEndReached方法;onEndReached={this.onEndReached}上拉加载实现,如下:
/** * 上拉加载 * @return {void} */ onEndReached = () => { this.getList(false); }
注:this.getList(false);方法同下拉刷新,参数false代表上拉加载。
9.ItemSeparatorComponent={ItemSeparatorComponent} 自定义一个分割线,如下:
export const ItemSeparator = props => { const { paddingLeft = px(40), backgroundColor = '#fff', borderColor = '#eee', } = props; return ( <View style={{paddingLeft, backgroundColor}}> <View style={{height: 1, backgroundColor: borderColor}}></View> </View> );};
10.keyExtractor={keyExtractor} 使用当前数据的id即可,如下:
keyExtractor={item => item.id}
11.ListHeaderComponent={this.renderListHeader} 头部的渲染,代码如下:
/** * 渲染列表头部 */ renderListHeader = () => { const { count } = this.state; const { ListHeaderComponent = () => <View></View> } = this.props; return ListHeaderComponent(this.state); }
注:布局根据自己的需求进行定义即可。
12.ListFooterComponent={showFooterBoo ? this.renderListFooter : null} 属性showFooterBoo布尔值用来控制是否显示脚,脚的布局定义如下:
/** * 渲染列表底部 * @return {ReactComponent} */ renderListFooter = () => { const { ListFooterComponent = this.defaultListFooter } = this.props; const { isEnd, refreshing } = this.state; return this.defaultListFooter(isEnd, refreshing); }
/** * 列表默认底部组件 * @return {Node} */ defaultListFooter = () => { return ( <FlexView justify="center" align="center" style={styles.listFooterView}> {this.defaultListFooterContent()} </FlexView> ); }
/** * 列表底部显示内容 * @return {Node} */ defaultListFooterContent = () => { const { isEnd, refreshing, isNotList, isError } = this.state; if(isNotList) { return ( <_Text>未查询到相关数据!</_Text> ); } if(isEnd) { return [ <FlexItem style={styles.listFooterLine} key={1}/>, <_Text key={2}>没有更多数据</_Text>, <FlexItem style={styles.listFooterLine} key={3}/>, ]; } if(refreshing) { return ( <_Text>正在加载...</_Text> ); } if(isError) { return ( <_Text>查询失败,下拉重新加载!</_Text> ); } return ( <_Text>上拉加载更多</_Text> ); }
注:脚的布局可以根据自己的项目需求进行更改。
13.ListEmptyComponent={this.renderListEmpty} 空布局,没有数据,请求出错显示,代码如下:
/** * 列表为空时显示的组件 * @return {ReactComponent} */ renderListEmpty = () => { return ( <View> <Text>没有数据哦!</Text> </View> ); }
14.ref={ref => this._listRef = ref} 当前实例
ok,总结就到这里了,后续我会总结更多的使用组件的~~
- react-native之上拉加载,下拉刷新组件封装
- 使用react-native,reduce开发简洁且的上拉刷新下拉加载更多的组件
- react native实现上拉加载下拉刷新
- react native实现上拉加载下拉刷新
- RN-react-native-pull-下拉刷新、上拉加载
- react-native-pull实现上拉加载下拉刷新
- 《React-Native系列》19、 ListView组件之上拉刷新(iOS和Android通用)
- 《React-Native系列》19、 ListView组件之上拉刷新(iOS和Android通用)
- React Native (五):上下拉刷新加载
- 自定义控件之上拉刷新下拉加载RefreshListView
- 微信小程序之上拉加载和下拉刷新
- react native FlatList使用详解以及上拉刷新下拉加载带可运行demo
- React-native IT喵~ ScrollView 嵌套ListView 如何实现上拉加载、下拉刷新
- react native listview上拉加载更多下拉刷新兼容ios 安卓
- React Native ListView上拉刷新,下拉加载刷新,并添加网络无数据时的缺省图
- weex学习之路(二)---组件封装(2)--下拉刷新和上拉加载
- react native之listview加下拉刷新上拉分页
- react-native纯JS上下拉刷新组件
- WEB前端 -- 关系选择器、属性选择器
- Nginx——2
- 双端链表
- oracle查询锁表与解锁
- LeetCod 339.Nested List Weight Sum
- react-native之上拉加载,下拉刷新组件封装
- 重写Spring MVC WEB 简单入门-登录例子
- 常用 工具 类
- 欢迎使用CSDN-markdown编辑器
- c语言输出类型
- 淘宝“避冬锦囊”中存在的安全隐患
- Unity基础,Line Renderer 和射线的应用
- IDEA中Git的使用
- navicat for mysql破解/注册码