


How to use Native in React to implement custom pull-down to refresh the list loaded by pull-up
This article mainly introduces the example of React Native customizing the pull-down to refresh the pull-up loaded list. Now I share it with you and give it as a reference.
List pages are very common pages in mobile development. In React Native, we generally use FlatList or SectionList components to implement these list views. Usually the list page will have a large amount of data that needs to be loaded and displayed. At this time, paging loading is used. Therefore, for the list component, it is essential to implement pull-down refresh and pull-up loading in many cases.
This article encapsulates a RefreshListView based on FlatList that supports pull-down refresh and pull-up loading. After encapsulating the original FlatList, it is very convenient to call pull-up and pull-down refresh.
The implementation of pull-down refresh is very simple. Here we use the properties of FlatList itself to implement
onRefresh— After setting this option, a standard will be added to the head of the list RefreshControl control in order to implement the "pull-down refresh" function. At the same time you need to set the refreshing attribute correctly.
refreshing—— bool value, used to control the display and hiding of the refresh control. Set to false after the refresh is complete.
By setting these two properties, we can realize the refresh operation of the FlatList header. The control uses the default style, and Android and iOS use the components of their respective systems to display.
The key point is to pull up to load more. React Native’s list component does not have this function and we need to implement it ourselves. For pull-up loading, we usually have several states. Here I create a RefreshState.js file to store the pull-up loading state:
export default { Idle: 'Idle', // 初始状态,无刷新的情况 CanLoadMore: 'CanLoadMore', // 可以加载更多,表示列表还有数据可以继续加载 Refreshing: 'Refreshing', // 正在刷新中 NoMoreData: 'NoMoreData', // 没有更多数据了 Failure: 'Failure' // 刷新失败 }
Then encapsulate a RefreshFooter component based on these states so that it can be customized according to different states. The status displays different contents. Without further ado, let’s talk about the code:
import React, {Component} from 'react'; import {View, Text, ActivityIndicator, StyleSheet, TouchableOpacity} from 'react-native'; import RefreshState from './RefreshState'; import PropTypes from 'prop-types'; export default class RefreshFooter extends Component { static propTypes = { onLoadMore: PropTypes.func, // 加载更多数据的方法 onRetryLoading: PropTypes.func, // 重新加载的方法 }; static defaultProps = { footerRefreshingText: "努力加载中", footerLoadMoreText: "上拉加载更多", footerFailureText: "点击重新加载", footerNoMoreDataText: "已全部加载完毕" }; render() { let {state} = this.props; let footer = null; switch (state) { case RefreshState.Idle: // Idle情况下为null,不显示尾部组件 break; case RefreshState.Refreshing: // 显示一个loading视图 footer = <View style={styles.loadingView}> <ActivityIndicator size="small"/> <Text style={styles.refreshingText}>{this.props.footerRefreshingText}</Text> </View>; break; case RefreshState.CanLoadMore: // 显示上拉加载更多的文字 footer = <View style={styles.loadingView}> <Text style={styles.footerText}>{this.props.footerLoadMoreText}</Text> </View>; break; case RefreshState.NoMoreData: // 显示没有更多数据的文字,内容可以自己修改 footer = <View style={styles.loadingView}> <Text style={styles.footerText}>{this.props.footerNoMoreDataText}</Text> </View>; break; case RefreshState.Failure: // 加载失败的情况使用TouchableOpacity做一个可点击的组件,外部调用onRetryLoading重新加载数据 footer = <TouchableOpacity style={styles.loadingView} onPress={()=>{ this.props.onRetryLoading && this.props.onRetryLoading(); }}> <Text style={styles.footerText}>{this.props.footerFailureText}</Text> </TouchableOpacity>; break; } return footer; } } const styles = StyleSheet.create({ loadingView: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', padding: 15, }, refreshingText: { fontSize: 12, color: "#666666", paddingLeft: 10, }, footerText: { fontSize: 12, color: "#666666" } });
Note that propTypes is the method we define for the RefreshFooter component for external calls. The method type needs to be specified using PropTypes, and Facebook’s prop-types need to be installed. For dependent libraries, it is best to use yarn add prop-types to install them, which is less error-prone. This is used for runtime type checking. You can click here to learn more.
In defaultProps we define several default text contents in different states, which can be modified by passing values externally.
The next step is to implement this RefreshListView. First of all, it should be clear that this RefreshListView must have head refresh and tail refresh calling methods, and the specific method of calling data should be implemented externally. First define two methods like RefreshFooter:
static propTypes = { onHeaderRefresh: PropTypes.func, // 下拉刷新的方法,供外部调用 onFooterRefresh: PropTypes.func, // 上拉加载的方法,供外部调用 };
As mentioned above, the pull-down refresh of the head is implemented using FlatList’s own features. We need to define a bool value isHeaderRefreshing as the value of the refreshing attribute to control the display and display of the header. no. At the same time, define an isFooterRefreshing to determine the refresh status of the tail component. Define footerState to set the state of the current tail component as the value of RefreshFooter.
constructor(props) { super(props); this.state = { isHeaderRefreshing: false, // 头部是否正在刷新 isFooterRefreshing: false, // 尾部是否正在刷新 footerState: RefreshState.Idle, // 尾部当前的状态,默认为Idle,不显示控件 } }
render function is as follows:
render() { return ( <FlatList {...this.props} onRefresh={()=>{ this.beginHeaderRefresh() }} refreshing={this.state.isHeaderRefreshing} onEndReached={() => { this.beginFooterRefresh() }} onEndReachedThreshold={0.1} // 这里取值0.1(0~1之间不包括0和1),可以根据实际情况调整,取值尽量小 ListFooterComponent={this._renderFooter} /> ) } _renderFooter = () => { return ( <RefreshFooter state={this.state.footerState} onRetryLoading={()=>{ this.beginFooterRefresh() }} /> ) };
You can see that there are two methods, beginHeaderRefresh and beginFooterRefresh, in the above code. These two methods are used to call refresh, but before refreshing, there are Some logical situations require judgment. For example, the head and tail cannot be refreshed at the same time, otherwise the data processing results may be affected. Repeated refresh operations must be prevented during refreshing. These are all considerations. Here I have commented in detail in the code:
/// 开始下拉刷新 beginHeaderRefresh() { if (this.shouldStartHeaderRefreshing()) { this.startHeaderRefreshing(); } } /// 开始上拉加载更多 beginFooterRefresh() { if (this.shouldStartFooterRefreshing()) { this.startFooterRefreshing(); } } /*** * 当前是否可以进行下拉刷新 * @returns {boolean} * * 如果列表尾部正在执行上拉加载,就返回false * 如果列表头部已经在刷新中了,就返回false */ shouldStartHeaderRefreshing() { if (this.state.footerState === RefreshState.refreshing || this.state.isHeaderRefreshing || this.state.isFooterRefreshing) { return false; } return true; } /*** * 当前是否可以进行上拉加载更多 * @returns {boolean} * * 如果底部已经在刷新,返回false * 如果底部状态是没有更多数据了,返回false * 如果头部在刷新,则返回false * 如果列表数据为空,则返回false(初始状态下列表是空的,这时候肯定不需要上拉加载更多,而应该执行下拉刷新) */ shouldStartFooterRefreshing() { if (this.state.footerState === RefreshState.refreshing || this.state.footerState === RefreshState.NoMoreData || this.props.data.length === 0 || this.state.isHeaderRefreshing || this.state.isFooterRefreshing) { return false; } return true; }
The logic of startHeaderRefreshing and startFooterRefreshing is as follows:
/// 下拉刷新,设置完刷新状态后再调用刷新方法,使页面上可以显示出加载中的UI,注意这里setState写法 startHeaderRefreshing() { this.setState( { isHeaderRefreshing: true }, () => { this.props.onHeaderRefresh && this.props.onHeaderRefresh(); } ); } /// 上拉加载更多,将底部刷新状态改为正在刷新,然后调用刷新方法,页面上可以显示出加载中的UI,注意这里setState写法 startFooterRefreshing() { this.setState( { footerState: RefreshState.Refreshing, isFooterRefreshing: true }, () => { this.props.onFooterRefresh && this.props.onFooterRefresh(); } ); }
Before refreshing, we need to display the head or tail components and then call External data interface methods. The advantage of writing setState here is that the methods in the arrow function will be called only after the value in the state is updated. There is a strict order. If this.props.onFooterRefresh && this.props.onFooterRefresh() is written outside setState, On the UI, we may not see the loading in the head or the hard loading in the tail, but the interface method has already been called.
Finally, after the refresh is completed, we also need to call the stop refresh method so that the head or tail components are no longer displayed. Otherwise, it may be considered a bug if it is always loading. Let’s take a look at how to stop refreshing:
/** * 根据尾部组件状态来停止刷新 * @param footerState * * 如果刷新完成,当前列表数据源是空的,就不显示尾部组件了。 * 这里这样做是因为通常列表无数据时,我们会显示一个空白页,如果再显示尾部组件如"没有更多数据了"就显得很多余 */ endRefreshing(footerState: RefreshState) { let footerRefreshState = footerState; if (this.props.data.length === 0) { footerRefreshState = RefreshState.Idle; } this.setState({ footerState: footerRefreshState, isHeaderRefreshing: false, isFooterRefreshing: false }) }
Passing in a tail component status parameter here is to update the style of the tail component. At the same time, a judgment is made on the data source data. If it is empty, it means that there is currently no data and a blank page can be displayed. Then there is no need to display the tail component.
The following is the rendering of the Douban movie page page loading that I implemented using RefreshListView:
The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.
Related articles:
Examples of set deduplication, intersection, union, and difference set functions implemented by JS
setTimeout time is set to 0Detailed analysis of
The method of index.js configuration file in the config directory of vue-cli scaffolding
The above is the detailed content of How to use Native in React to implement custom pull-down to refresh the list loaded by pull-up. For more information, please follow other related articles on the PHP Chinese website!

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

The differences in performance and efficiency between Python and JavaScript are mainly reflected in: 1) As an interpreted language, Python runs slowly but has high development efficiency and is suitable for rapid prototype development; 2) JavaScript is limited to single thread in the browser, but multi-threading and asynchronous I/O can be used to improve performance in Node.js, and both have advantages in actual projects.

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.

JavaScript runs in browsers and Node.js environments and relies on the JavaScript engine to parse and execute code. 1) Generate abstract syntax tree (AST) in the parsing stage; 2) convert AST into bytecode or machine code in the compilation stage; 3) execute the compiled code in the execution stage.

The future trends of Python and JavaScript include: 1. Python will consolidate its position in the fields of scientific computing and AI, 2. JavaScript will promote the development of web technology, 3. Cross-platform development will become a hot topic, and 4. Performance optimization will be the focus. Both will continue to expand application scenarios in their respective fields and make more breakthroughs in performance.

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

Yes, the engine core of JavaScript is written in C. 1) The C language provides efficient performance and underlying control, which is suitable for the development of JavaScript engine. 2) Taking the V8 engine as an example, its core is written in C, combining the efficiency and object-oriented characteristics of C. 3) The working principle of the JavaScript engine includes parsing, compiling and execution, and the C language plays a key role in these processes.

JavaScript is at the heart of modern websites because it enhances the interactivity and dynamicity of web pages. 1) It allows to change content without refreshing the page, 2) manipulate web pages through DOMAPI, 3) support complex interactive effects such as animation and drag-and-drop, 4) optimize performance and best practices to improve user experience.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Dreamweaver CS6
Visual web development tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

Atom editor mac version download
The most popular open source editor

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.
