我尝试用交叉观察器实现无限滚动。我面临的问题是,当我到达倒数第二个位置时,api调用会触发并加载数据。
但是api调用发生了两次,我应该在这段代码中更新什么。
// app.js
import React, {Component} from 'react'
import Child from './child'
import axios from 'axios'
class App extends Component {
state = {
users: [],
page: 0,
loading: false,
prevY: 0,
isDataAvailable: false,
}
componentDidMount() {
this.getUsers(this.state.page)
}
getUsers = (page = this.state.page) => {
this.setState({loading: true})
axios
.get(`https://api.github.com/users?since=${page}&per_page=100`)
.then(res => {
console.log({users: res.data})
this.setState({users: [...this.state.users, ...res.data]})
this.setState({loading: false, isDataAvailable: true})
})
}
handleObserver = (entities, observer) => {
const y = entities[0].boundingClientRect.y
if (this.state.prevY > y) {
const lastUser = this.state.users[this.state.users.length - 1]
const curPage = lastUser.id
this.getUsers(curPage)
this.setState({page: curPage})
}
this.setState({prevY: y})
}
render() {
return (
<div className="container">
<div style={{minHeight: '800px'}}>
{this.state.isDataAvailable ? (
<Child
handleObserver={this.handleObserver}
users={this.state.users}
/>
) : null}
</div>
</div>
)
}
}
export default App
// child.js
import React, {Component} from 'react'
class Child extends Component {
componentDidMount() {
const options = {
root: null,
threshold: 0,
}
this.observer = new IntersectionObserver(
this._handleObserver.bind(this),
options,
)
this.observer.observe(this.loadingRef)
}
shouldComponentUpdate(nextProps) {
return this.props.users !== nextProps.users
}
componentDidUpdate() {
this.observer.observe(this.loadingRef)
}
_handleObserver(entities, observer) {
console.log('called')
this.props.handleObserver(entities)
}
render() {
return (
<ul>
{this.props.users.map((user, index) =>
index === this.props.users.length - 1 ? (
<div>
<div ref={loadingRef => (this.loadingRef = loadingRef)}>
<b>
<h1>Target</h1>
</b>
</div>
<li key={user.id}>{user.login}</li>
</div>
) : (
<li key={user.id}>{user.login}</li>
),
)}
</ul>
)
}
}
export default Child
任何帮助表示赞赏
请查看代码框和代码框控制台,您可以看到两次API调用发生时,到达目标时我仅需要调用一项服务。每个向下滚动100个结果。