实现点击加载更多按钮,以及上拉加载更多数据
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 方法。