详情
我正在使用tRPC和useInfiniteQuery在一个nextjs twitter克隆中创建无限滚动效果。我相信这工作正常。我已经测试过了,我可以获取下一页的tweet。
不过我做了一个自定义钩子,它会检查用户当前位置在页面上的位置,状态看起来根本没有更新。它会在页面加载时获取滚动位置,仅此而已。
Feed组件代码
// Dependencies
import Link from 'next/link';
import { useState, useEffect } from 'react';
// API
import { api } from '~/utils/api';
// Components
import { LoadingSpinner } from '~/components/LoadingSpinner';
import { TweetView } from '~/components/TweetView';
function useScrollPosition() {
const [scrollPosition, setScrollPosition] = useState(0);
const handleScroll = () => {
const height =
document.documentElement.scrollHeight -
document.documentElement.clientHeight;
const winScroll =
document.body.scrollTop || document.documentElement.scrollTop;
const scrolled = (winScroll / height) * 100;
setScrollPosition(scrolled);
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
return scrollPosition;
}
// Feed Limit
const LIMIT = 10;
export const Feed = () => {
const {
data,
isLoading: tweetsLoading,
hasNextPage,
fetchNextPage,
isFetching,
} = api.tweet.getAll.useInfiniteQuery(
{
limit: LIMIT,
},
{
getNextPageParam: (lastPage) => lastPage.nextCursor,
}
);
const scrollPosition = useScrollPosition();
const tweets = data?.pages.flatMap((page) => page.tweetsWithUsers) ?? [];
console.log(scrollPosition);
useEffect(() => {
const nextTweetPage = async () => {
// Get the next page of data if the scroll position is at x
if (scrollPosition > 90 && hasNextPage && !isFetching) {
await fetchNextPage();
}
};
nextTweetPage().catch((e) => console.log(e));
}, [scrollPosition, hasNextPage, isFetching, fetchNextPage]);
if (tweetsLoading) {
return (
<div className="mt-4 flex h-screen items-center justify-center">
<LoadingSpinner size={40} />
</div>
);
}
if (!data) {
return (
<div className="flex flex-col items-center justify-center gap-6 p-6 text-center">
<h3>{`Hmmm... Something went wrong getting these twoots, try refreshing?`}</h3>
<Link
href="/"
className="rounded-full bg-bright-pink py-2.5 px-3.5 text-base font-bold text-white shadow-sm hover:bg-pink-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-bright-pink"
>
Home
</Link>
</div>
);
}
return (
<div className="h-full">
{tweets.map((fullTweet) => (
<TweetView
tweetData={{ ...fullTweet }}
key={fullTweet.tweet.id}
input={{ limit: LIMIT }}
/>
))}
</div>
);
};
我做了什么
我试过寻找其他的解决方案,比如useCallback,也试过其他类似的堆栈溢出问题,但没有一个解决方案是有效的。
被难倒在这一段时间,我不能前进的项目没有这个工作。
1条答案
按热度按时间zujrkrfu1#
当前Hacky解决方案
我今天需要让这个工作现实。我使用了一个名为react-intersection-observer的包。创建了一个div,它将呈现在提要的底部。一旦带有交叉引用的div进入视图,下一页将被获取。
我有点恼火,我不能让挂钩工作,无论什么原因。但这做的工作刚刚好。
这是代码,如果其他人正在挣扎。
Feed组件