載入更多功能實現
阿新 • • 發佈:2019-02-08
實現點選載入更多按鈕,以及上拉載入更多資料
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 方法。