react native Expo完全基于ScrollView实现的下拉刷新和上拉触底加载

Posted DellYoung

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react native Expo完全基于ScrollView实现的下拉刷新和上拉触底加载相关的知识,希望对你有一定的参考价值。

我直接封装成了一个组件

props参数为

static propTypes = {
        style:PropTypes.object, // 样式
        refreshing:PropTypes.bool.isRequired,//是否开始下拉刷新动画
        refreshBegin: PropTypes.func,// 开始下拉刷新回调
        scrollEnd: PropTypes.func,// 触底回调
    };

使用示例

import React from ‘react‘;
import {
    View,
} from ‘react-native‘;
import styles from ‘./style‘;
import HomeSwiper from "../../../components/HomeSwiper";
import HomeVideo from "../../../components/HomeVideo";
import ScrollViewPull from "../../../components/ScrollViewPull";
import {connect} from ‘react-redux‘; // 引入connect函数
import {
    getHomeSwiper,
    getHomeVideoCard,
    handleRefreshStatus
} from ‘../../../actions/homeRecommendAction‘;

class HomeRecommend extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            refreshing: false,
        };
    }

    componentDidMount(){
        const {homeVideoCard} = this.props;
        this.props.getVideoCard(undefined,1,homeVideoCard);
        this.props.getSwiper();
    }

    // 触底
    handleScrollEnd = () => {
        const {currentPage,lastPage,homeVideoCard} = this.props;
        if(currentPage === lastPage){
            this.props.getVideoCard(undefined,currentPage+1,homeVideoCard);
        }
    };

    // 开始下拉刷新
    handleRefreshBegin = () => {
        const {homeVideoCard} = this.props;
        this.props.getChangeRefresh(true);
        this.props.getSwiper();
        this.props.getVideoCard(undefined,1,homeVideoCard);
    };

    render() {
        const {navigation,swiperData,leftVideoData,rightVideoData,refreshing} = this.props;
        return (
            <ScrollViewPull
                style={styles.scroll}
                refreshing={refreshing}
                scrollEnd={()=>this.handleScrollEnd()} // 触底回调
                refreshBegin={()=>this.handleRefreshBegin()} // 开始下拉刷新回调
            >
                <View style={styles.container}>
                    <HomeSwiper
                        navigation={navigation}
                        swiperData={swiperData}
                    />
                    <View style={styles.border}/>
                    <HomeVideo
                        navigation={navigation}
                        leftVideoData={leftVideoData}
                        rightVideoData={rightVideoData}
                    />
                </View>
            </ScrollViewPull>
        );
    }
}

const mapStateToProps = (state) => ({
    swiperData : state.homeRecommend.homeSwiperData,
    currentPage : state.homeRecommend.currentPage,
    homeVideoCard: state.homeRecommend.homeVideoCard,
    leftVideoData : state.homeRecommend.leftVideoData,
    rightVideoData : state.homeRecommend.rightVideoData,
    refreshing: state.homeRecommend.refreshing
});

const mapDispatchToProps = (dispatch) => ({
    getSwiper(){
        dispatch(getHomeSwiper());
    },
    getChangeRefresh(refresh){
        dispatch(handleRefreshStatus(refresh));
    },
    getVideoCard(id,page,homeVideoCard){
        dispatch(getHomeVideoCard(id,page,homeVideoCard));
    },
});

export default connect(mapStateToProps,mapDispatchToProps)(HomeRecommend);

组件全部代码为:

import React from ‘react‘;
import {
    ScrollView,
    RefreshControl,
} from ‘react-native‘;
import PropTypes from ‘prop-types‘;

class ScrollViewPull extends React.Component {
    static navigationOptions = {
        header: null,
    };

    static propTypes = {
        style:PropTypes.object, // 样式
        refreshing:PropTypes.bool.isRequired,//是否开始下拉刷新动画
        refreshBegin: PropTypes.func,// 开始下拉刷新回调
        scrollEnd: PropTypes.func,// 触底回调
    };

    constructor(props) {
        super(props);
        this.initState();
    }


    initState=()=>{

    };

    onRefresh = () => {
        this.props.refreshBegin();
    };

    // 监听上拉触底
    _contentViewScroll = (e: Object) => {
        let offsetY = e.nativeEvent.contentOffset.y; //滑动距离
        let contentSizeHeight = e.nativeEvent.contentSize.height; //scrollView contentSize高度
        let oriageScrollHeight = e.nativeEvent.layoutMeasurement.height; //scrollView高度
        if (offsetY + oriageScrollHeight >= contentSizeHeight){
            this.props.scrollEnd();
        }
    };

    render() {
        const {children,refreshing,style} = this.props;
        return (
            <ScrollView
                style={[{flex:1},style]}
                showsVerticalScrollIndicator={false}
                scrollToIndex
                refreshControl={
                    <RefreshControl
                        refreshing={refreshing}
                        onRefresh={this.onRefresh}
                    />
                }
                onMomentumScrollEnd = {this._contentViewScroll}
            >
                {children}
            </ScrollView>
        );
    }
}

export default ScrollViewPull;

  

以上是关于react native Expo完全基于ScrollView实现的下拉刷新和上拉触底加载的主要内容,如果未能解决你的问题,请参考以下文章

我们如何将 Firebase Analytics 与基于 expo 的 react-native 应用程序一起使用

Expo - 网络响应超时错误 (create-react-native-app) (Windows 10)

在 Expo Go 上加载 Expo React Native 时遇到问题

无法注销。基于 Auth0 的 React Native Expo 应用程序

React-native (expo) - 无效类型

React Native - 如何构建 expo react native 应用程序,使其不需要 Expo android 应用程序打开