Skip to content

Instantly share code, notes, and snippets.

@jaredpalmer
Forked from lelandrichardson/InfiniteScroll.js
Created March 2, 2017 20:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaredpalmer/70769990f79dfaf38f45b27687dc2955 to your computer and use it in GitHub Desktop.
Save jaredpalmer/70769990f79dfaf38f45b27687dc2955 to your computer and use it in GitHub Desktop.
Super Light Infinite Scroll Component in React
var React = require('react');
var { Component, PropTypes } = React;
var throttle = require('lodash/function/throttle');
class InfiniteScroll extends React.Component {
static propTypes = {
hasMore: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
onLoadMore: PropTypes.func.isRequired,
threshold: PropTypes.number,
throttle: PropTypes.number
};
static defaultProps = {
threshold: 100,
throttle: 64
};
constructor(props, context) {
super(props, context);
this.check = throttle(this.check.bind(this), props.throttle);
}
check() {
var { isLoading, hasMore, threshold, onLoadMore } = this.props;
if (isLoading || !hasMore) {
return;
}
var sentinel = this.refs.sentinel.getDOMNode();
var fromBottom = sentinel.getBoundingClientRect().top - window.innerHeight;
if (fromBottom < threshold) {
onLoadMore();
}
}
componentDidMount() {
window.addEventListener('scroll', this.check);
window.addEventListener('resize', this.check);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.check);
window.removeEventListener('resize', this.check);
}
render() {
return (
<div>
{this.props.children}
<div ref="sentinel" />
</div>
);
}
}
module.exports = InfiniteScroll;
class List extends React.Component {
onLoadMore() {
// ...
}
render() {
const { items, total, loading } = this.props;
return (
<div>
<InfiniteScroll
hasMore={items.length < items.total}
isLoading={loading}
onLoadMore={::this.onLoadMore}
>
<ul>
{items.map(item =>
<Item key={item.id} item={item} />
)}
</ul>
</InfiniteScroll>
<div>
{loading && "Loading..."}
{hasMore && <Link to={...}>Load More...</Link>}
</div>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment