@e-group/hooks
Version:
eGroup team react-hooks that share across projects.
60 lines (53 loc) • 2.48 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import React from 'react';
const getScrollPosition = ref => {
if (typeof ref.scrollY === 'number') {
return ref.innerHeight + ref.scrollY;
}
return ref.scrollTop + ref.offsetHeight;
};
const isBrowser = typeof document !== 'undefined';
export default function makeInfiniteScroll(options = {}) {
const _options$offset = options.offset,
offset = _options$offset === void 0 ? 100 : _options$offset,
_options$disableDefau = options.disableDefaultTarget,
disableDefaultTarget = _options$disableDefau === void 0 ? false : _options$disableDefau;
return function useInfiniteScroll(options = {}) {
const defaultTarget = typeof window !== 'undefined' ? window : null;
const defaultScrollHeight = isBrowser ? document.body.scrollHeight : null;
const _options$target = options.target,
target = _options$target === void 0 ? !disableDefaultTarget ? defaultTarget : undefined : _options$target,
_options$scrollHeight = options.scrollHeight,
scrollHeight = _options$scrollHeight === void 0 ? !disableDefaultTarget ? defaultScrollHeight : undefined : _options$scrollHeight,
_options$defaultPage = options.defaultPage,
defaultPage = _options$defaultPage === void 0 ? 0 : _options$defaultPage,
isLoading = options.isLoading,
maxPage = options.maxPage;
const _React$useState = React.useState(defaultPage),
_React$useState2 = _slicedToArray(_React$useState, 2),
page = _React$useState2[0],
setPage = _React$useState2[1];
const handleScroll = React.useCallback(() => {
if (isLoading) return;
if (getScrollPosition(target) + offset >= scrollHeight) {
setPage(value => {
const nextPage = value + 1;
if (nextPage > maxPage) return value;
return nextPage;
});
}
}, [isLoading, maxPage, scrollHeight, target]);
React.useEffect(() => {
if (typeof target === 'undefined' || typeof scrollHeight === 'undefined') return;
/**
* Event listener will resubscribe every time when arguments change.
* And this can avoid subscribe multiple listeners.
*/
target.addEventListener('scroll', handleScroll);
return () => {
target.removeEventListener('scroll', handleScroll);
};
}, [handleScroll, scrollHeight, target]);
return [page, setPage];
};
}