1. 程式人生 > >載入更多功能實現

載入更多功能實現

實現點選載入更多按鈕,以及上拉載入更多資料

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: 1 } } 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
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
  • hasMore控制組件的顯示和隱藏
  • isLoadingMore控制組件是顯示“載入中…”(此時點選失效)還是“點選載入更多”
  • loadMoreData函式會在點選元件時觸發,並載入下一頁資料
  • page記錄下一頁的頁碼,會在loadMoreData函式中使用並累加

監控 window 的scroll方法,然後獲取ref="wrapper"的DOM,利用getBoundingClientRect()方法獲得距離底部的高度,然後看是否觸發 loadMore 方法。