做法:
(1)在组件挂载后,绑定滑动事件,使用ref获取到该组件对象
(2)组件对象调用getBoundingClientRect()获取到该组件距离页面顶部的距离(不包括元素自身)
(3)通过判断该组件距离页面顶部的距离和页面本身的高度,如果小于页面本身的高度,则发生网络请求获取更多数据
节流防抖:
在定时器中设置网络请求,下一次触发时,清除掉上一次的定时器,保留当前的定时器,若在
定时器设置的延迟时间内再次触发,会被清除掉,只保留当前最新的网络请求
参数传递
该组件仅有提示信息,需要的网络请求参数设置都通过参数传递
加载更多数据:父组件传递可以使得参数增加的函数
无更多数据:父组件传递终止条件
组件卸载前取消绑定事件和未到的网络请求
代码示例:
上拉加载组件:
import React,{Component} from 'react'
import './style.less'
class App extends Component{
constructor()
{
super();
this.load=React.createRef();
}
componentDidMount()
{
if(this.props.hasMore)
{
//获取页面高度
const winHeight=document.documentElement.clientHeight;
var timer=null;
//节流防抖
window.onscroll=(event)=>{
//若在300毫秒内又触发,取消上一次,保留当前这一次
if(timer)
{
clearTimeout(timer);
}
timer=setTimeout(()=>{
if(this.load.current.getBoundingClientRect().top<winHeight)
{
this.props.onLoadMore();
}
},300)
}
}
}
//卸载前解除绑定事件和未到的网络请求
componentWillUnmount()
{
window.onScroll=null;
this.setState=(state,callback)=>{
return ;
}
}
render()
{
return(
<div ref={this.load}>
{
this.props.hasMore?'加载更多':'无更多数据'
}
</div>
)
}
}
export default App
父组件:
import React,{Component} from 'react'
import {getSearchData} from '../../../fetch/search/index'
import SearchListView from '../../../components/SearchListView/index'
import LoadMore from '../../../components/LoadMore/index'
class App extends Component{
state={
searchData:{},
hasMore:true
}
async componentWillMount()
{
const res=await getSearchData(this.props.city,this.props.keywords);
this.setState({
searchData:res.data
})
}
//改变数据多次获取
async componentWillUpdate(preProps,preState)
{
if(this.props.keywords!=preProps.keywords)
{
const res=await getSearchData(this.props.city,this.props.keywords);
this.setState({
searchData:res.data
})
}
}
//上拉加载更多
loadMoreHandler=async ()=>{
const res=await getSearchData(this.props.city,this.props.keywords);
console.log(res.hasMore);
this.setState({
searchData:this.state.searchData.concat(res.data),
hasMore:res.hasMore
})
}
render()
{
return(
<div>
{
this.state.searchData.length>0?<SearchListView data={this.state.searchData}></SearchListView>
: <div>数据加载中</div>
}
<LoadMore onLoadMore={this.loadMoreHandler} hasMore={this.state.hasMore}/>
</div>
)
}
}
export default App