Use IntersectionObserver to paginate

This commit is contained in:
Sonny Bakker 2022-05-26 17:28:41 +02:00
parent ff6dfcaa05
commit fedeed15c5
2 changed files with 36 additions and 11 deletions

View file

@ -35,7 +35,7 @@ class PostItem extends React.Component {
} }
return ( return (
<li className="posts__item"> <li className="posts__item" data-id={post.id}>
<h5 <h5
className={titleClassName} className={titleClassName}
title={post.title} title={post.title}

View file

@ -10,24 +10,49 @@ import LoadingIndicator from '../../../../components/LoadingIndicator.js';
import PostItem from './PostItem.js'; import PostItem from './PostItem.js';
class PostList extends React.Component { class PostList extends React.Component {
checkScrollHeight = ::this.checkScrollHeight; handleIntersect = ::this.handleIntersect;
observer = null;
lastPost = null;
callCount = 0;
componentDidMount() { constructor(props) {
window.addEventListener('scroll', this.checkScrollHeight); super(props);
const observerOptions = { root: null, rootMargin: '0px', threshold: 0 };
this.observer = new IntersectionObserver(this.handleIntersect, observerOptions);
}
componentDidUpdate() {
const lastPost = [...this.props.postsByType]
.reverse()
.find(post => post.read === false);
if (lastPost && (!this.lastPost || lastPost.id != this.lastPost.id)) {
const observeTarget = document.querySelector(
`.posts__item[data-id="${lastPost.id}"]`
);
this.lastPost = lastPost;
this.observer.observe(observeTarget);
}
} }
componentWillUnmount() { componentWillUnmount() {
window.removeEventListener('scroll', this.checkScrollHeight); this.observer.disconnect();
} }
checkScrollHeight(e) { handleIntersect(entries) {
const postList = document.body.querySelector('.posts__list'); entries.every(entry => {
if (entry.isIntersecting) {
this.observer.unobserve(entry.target);
if (this.props.next && !this.props.lastReached) { if (this.props.next && !this.props.lastReached) {
if (window.scrollY + window.innerHeight >= postList.offsetHeight) { this.paginate();
this.paginate(); }
return false;
} }
} });
} }
paginate() { paginate() {