美文网首页
React 实现加载更多

React 实现加载更多

作者: allenzhan | 来源:发表于2017-09-15 16:54 被阅读0次

    app 下拉刷新和上拉加载是很常见的效果。
    今天尝试用react 来实现下拉加载和点击按钮加载更多的效果

    下面的代码是一个列表界面。将用下面代码来讲解怎么实现点击加载更多和下拉加载更多

    List 页面

    import React from 'react'
    import PureRenderMixin from 'react-addons-pure-render-mixin'
    import { getListData } from '../../../fetch/home/home'
    
    import ListCompoent from '../../../components/List'
    import LoadMore from '../../../components/LoadMore'
    
    import './style.less'
    
    class List extends React.Component {
        constructor(props, context) {
            super(props, context);
            this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
            this.state = {
                data: [], //数据源
                hasMore: false, //是否存在下一页
                isLoadingMore: false,//是否正在加载
                page: 0 //当前的页码
            }
        }
        render() {
            return (
                <div>
                    <h2 className="home-list-title">猜你喜欢</h2>
                    {
                        this.state.data.length
                        ? <ListCompoent data={this.state.data}/>
                        : <div>{/* 加载中... */}</div>
                    }
                    {
          
        //这里如果有下一页。就显示由下一页的按钮。没有显示为空
                        this.state.hasMore
                        ? <LoadMore isLoadingMore={this.state.isLoadingMore} loadMoreFn={this.loadMoreData.bind(this)}/>
                        : ''
                    }
                </div>
            )
        }
        componentDidMount() {
            // 获取首页数据
            this.loadFirstPageData()
        }
        // 获取首页数据
        loadFirstPageData() {
            const cityName = this.props.cityName
            const result = getListData(cityName, 0)
            this.resultHandle(result)
        }
        // 加载更多数据
        loadMoreData() {
            // 记录状态
            this.setState({
                isLoadingMore: true
            })
    
            const cityName = this.props.cityName
            const page = this.state.page
            const result = getListData(cityName, page)
            this.resultHandle(result)
    
            // 增加 page 技术
            this.setState({
                page: page + 1,
                isLoadingMore: false
            })
        }
        // 处理数据
        resultHandle(result) {
            result.then(res => {
                return res.json()
            }).then(json => {
                const hasMore = json.hasMore
                const data = json.data
    
                this.setState({
                    hasMore: hasMore,
                    // 注意,这里讲最新获取的数据,拼接到原数据之后,使用 concat 函数
                    data: this.state.data.concat(data)
                })
            }).catch(ex => {
                if (__DEV__) {
                    console.error('首页”猜你喜欢“获取数据报错, ', ex.message)
                }
            })
        }
    }
    export default List
    
    <LoadMore isLoadingMore={this.state.isLoadingMore} loadMoreFn={this.loadMoreData.bind(this)}/>
    

    传但当前的状态(是否加载)给LoadMore组件 以及回调方法loadMoreFn

    LoadMore

    import React from 'react'
    import PureRenderMixin from 'react-addons-pure-render-mixin'
    
    import './style.less'
    
    class LoadMore extends React.Component {
        constructor(props, context) {
            super(props, context);
            this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
        }
        render() {
            return (
                <div className="load-more" ref="wrapper">
                    {
    //如果正在加载中就显示加载中。不是就显示加载更多的按钮
                        this.props.isLoadingMore
                        ? <span>加载中...</span>
                        : <span onClick={this.loadMoreHandle.bind(this)}>加载更多</span>
                    }
                </div>
            )
        }
        loadMoreHandle() {
            // 执行传输过来的
            this.props.loadMoreFn();
        }
    
        //下拉加载更多的方法
        componentDidMount() {
            // 使用滚动时自动加载更多
            const loadMoreFn = this.props.loadMoreFn
            const wrapper = this.refs.wrapper
            let timeoutId
            function callback() {
                const top = wrapper.getBoundingClientRect().top
                const windowHeight = window.screen.height
                if (top && top < windowHeight) {
                    // 证明 wrapper 已经被滚动到暴露在页面可视范围之内了
                    loadMoreFn()
                }
            }
            window.addEventListener('scroll', function () {
                if (this.props.isLoadingMore) {
                    return
                }
                if (timeoutId) {
                    clearTimeout(timeoutId)
                }
                timeoutId = setTimeout(callback, 50)
            }.bind(this), false);
        }
    }
    
    export default LoadMore
    

    这样点击加载更多的时候就调用传多来的函数loadMoreFn.对应的就会执行loadMoreData()这个函数去加载更多的数据

    下拉加载

    原理就是监听屏幕的滚动。判断当前加载更多按钮是否已经出现在页面上。如果出现就直接加载更多。这里要做一个节流。就是当50ms 判断有没有第二次触发滚动,如果没有执行callback

     //下拉加载更多的方法
        componentDidMount() {
            // 使用滚动时自动加载更多
            const loadMoreFn = this.props.loadMoreFn
            const wrapper = this.refs.wrapper
            let timeoutId
            function callback() {
                //获取到按钮离顶部的距离
                const top = wrapper.getBoundingClientRect().top
                const windowHeight = window.screen.height
                if (top && top < windowHeight) {
                    // 证明 wrapper 已经被滚动到暴露在页面可视范围之内了
                    loadMoreFn()
                }
            }
            window.addEventListener('scroll', function () {
                if (this.props.isLoadingMore) {
                    return
                }
                if (timeoutId) {
                    clearTimeout(timeoutId)
                }
                //如果在50ms 以内没有执行scroll 就会执行callBack,如果有下一次滚动,定时器就会被清空
                timeoutId = setTimeout(callback, 50)
            }.bind(this), false);
        }
    

    相关文章

      网友评论

          本文标题:React 实现加载更多

          本文链接:https://www.haomeiwen.com/subject/yzassxtx.html