UNPKG

react-use-infinite-loading

Version:

Infinite scroll hook for React. Supports multiple scroll directions.

116 lines (102 loc) 3.05 kB
import { useRef, useState, useCallback, useEffect, useLayoutEffect } from 'react'; var useInfiniteScroll = function useInfiniteScroll(_ref) { var callback = _ref.callback, hasMore = _ref.hasMore, _ref$startPage = _ref.startPage, startPage = _ref$startPage === void 0 ? 1 : _ref$startPage, _ref$offset = _ref.offset, offset = _ref$offset === void 0 ? 250 : _ref$offset, direction = _ref.direction; var ref = useRef(null); var _useState = useState(false), firstScroll = _useState[0], setFirstScroll = _useState[1]; var containerRef = useRef(null); var _useState2 = useState(false), isLoading = _useState2[0], setIsLoading = _useState2[1]; var _useState3 = useState(startPage), page = _useState3[0], setPage = _useState3[1]; var setRef = useCallback(function (node) { if (node) { ref.current = node; } }, []); var setContainerRef = useCallback(function (node) { if (node) { containerRef.current = node; } }, []); var fetchData = function fetchData(page) { try { setIsLoading(true); return Promise.resolve(callback(page)).then(function () { setIsLoading(false); }); } catch (e) { return Promise.reject(e); } }; useEffect(function () { var func = function func() { try { return Promise.resolve(fetchData(page)).then(function () { if (direction === 'top') containerRef.current.scrollTo(0, offset); }); } catch (e) { return Promise.reject(e); } }; func(); }, [page]); useLayoutEffect(function () { if (!hasMore) return; var currentRef = ref.current; var options = { root: null, rootMargin: direction === 'bottom' ? "0px 0px " + offset + "px 0px" : offset + "px 0px 0px 0px" }; var loadMore = function loadMore(entries) { try { entries.forEach(function (_ref2) { var isIntersecting = _ref2.isIntersecting; if (isIntersecting && !isLoading) { setPage(function (prev) { return prev + 1; }); } }); return Promise.resolve(); } catch (e) { return Promise.reject(e); } }; var observer = new IntersectionObserver(loadMore, options); observer.observe(currentRef); return function () { observer.disconnect(); }; }, [ref, hasMore, isLoading]); useLayoutEffect(function () { if (direction === 'top' && !firstScroll) { containerRef.current.scrollIntoView({ block: 'end', inline: 'nearest' }); } }); useEffect(function () { window.addEventListener('scroll', function () { return setFirstScroll(true); }); return function () { return window.removeEventListener('scroll', function () { return setFirstScroll(true); }); }; }, []); return [setRef, setContainerRef, isLoading]; }; export default useInfiniteScroll; //# sourceMappingURL=index.modern.js.map