UNPKG

@e-group/hooks

Version:

eGroup team react-hooks that share across projects.

60 lines (53 loc) 2.48 kB
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]; }; }