react 触底加载 hook 封装
时间: 2023-11-21 17:05:00 浏览: 89
以下是一个React触底加载的Hook封装的示例代码:
```javascript
import { useState, useEffect } from 'react';
function useOnScreen(ref) {
const [isIntersecting, setIntersecting] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
setIntersecting(entry.isIntersecting);
},
{ rootMargin: '0px 0px 100px 0px' } // 设置触发时机
);
if (ref.current) {
observer.observe(ref.current);
}
return () => {
observer.unobserve(ref.current);
};
}, [ref]);
return isIntersecting;
}
function useScroll() {
const [scrollPosition, setScrollPosition] = useState(0);
useEffect(() => {
const updateScrollPosition = () => {
setScrollPosition(window.pageYOffset);
};
window.addEventListener('scroll', updateScrollPosition);
return () => window.removeEventListener('scroll', updateScrollPosition);
}, []);
return scrollPosition;
}
function useInfiniteScroll(callback) {
const [isFetching, setIsFetching] = useState(false);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
const ref = useRef();
const isIntersecting = useOnScreen(ref);
const scrollPosition = useScroll();
useEffect(() => {
if (isIntersecting && !isFetching && hasMore) {
setIsFetching(true);
callback(page).then((res) => {
if (res.length === 0) {
setHasMore(false);
} else {
setPage(page + 1);
}
setIsFetching(false);
});
}
}, [isIntersecting, isFetching, hasMore, page, callback]);
return [ref, scrollPosition];
}
```
这个Hook封装了一个无限滚动的功能,当用户滚动到页面底部时,会自动触发回调函数,从而实现无限滚动的效果。其中,`useOnScreen`是用来判断元素是否在可视区域内的Hook,`useScroll`是用来获取滚动条位置的Hook,`useInfiniteScroll`是用来封装无限滚动功能的Hook。
使用示例:
```javascript
function App() {
const [list, setList] = useState([]);
const [ref, scrollPosition] = useInfiniteScroll(fetchData);
function fetchData(page
阅读全文