Skip to content

Commit bd51476

Browse files
committed
feat: refactor scroll to load more
1 parent ab3a6e6 commit bd51476

File tree

6 files changed

+89
-72
lines changed

6 files changed

+89
-72
lines changed

apps/web/@/hooks/useInfinityScroll.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { useCallback, useEffect, useRef, useState } from "react"
22

3-
const useInfiniteScroll = (callback: () => void, root: HTMLElement | null, isFetching: boolean) => {
3+
const useInfiniteScroll = (callback: Function, root: HTMLElement | null, isFetching: boolean) => {
44
const observer = useRef<IntersectionObserver | null>(null)
55
const [node, setNode] = useState<HTMLElement | null>(null)
66

77
const handleIntersection = useCallback(
88
(entries: IntersectionObserverEntry[]) => {
9-
console.log("entries", entries)
109
if (entries[0].isIntersecting && !isFetching) {
1110
callback?.()
1211
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"use client"
2+
3+
import { Loader } from "lucide-react"
4+
5+
import useInfiniteScroll from "@/hooks/useInfinityScroll"
6+
7+
interface InfiniteScrollProps {
8+
containerClassName?: string
9+
children: React.ReactNode
10+
hasMore?: boolean
11+
root?: HTMLElement | null
12+
loading: boolean
13+
nextPage: (params: Record<string, any>) => Promise<any>
14+
}
15+
16+
export default function InfiniteScroll({
17+
containerClassName,
18+
children,
19+
hasMore,
20+
root,
21+
nextPage,
22+
loading,
23+
}: InfiniteScrollProps) {
24+
const { setNode } = useInfiniteScroll(nextPage, root, loading)
25+
26+
return (
27+
<div className={containerClassName}>
28+
{children}
29+
30+
<div
31+
ref={setNode}
32+
className="flex h-10 w-full items-center justify-center"
33+
>
34+
{loading && <Loader className="animate-spin" />}
35+
</div>
36+
</div>
37+
)
38+
}

apps/web/@/molecules/post-list/index.tsx

Lines changed: 0 additions & 67 deletions
This file was deleted.

apps/web/@/molecules/posts/post-item/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default function PostItem({ post }: { post: TPostItem }) {
4848
</div>
4949
</div>
5050
</div>
51-
{post.image && (
51+
{post.image && post.image.previewUrl && (
5252
<div className="flex items-center">
5353
<Image
5454
src={post.image.previewUrl}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"use client"
2+
3+
import React, { useCallback, useState } from "react"
4+
import { useParams } from "next/navigation"
5+
6+
import { getPosts, TPostItem } from "database"
7+
8+
import InfiniteScroll from "@/molecules/infinite-scroll"
9+
10+
import PostItem from "../post-item"
11+
12+
export default function PostList() {
13+
const searchParams = useParams()
14+
const [isLoading, setIsLoading] = useState(false)
15+
const [posts, setPosts] = useState<TPostItem[]>([])
16+
const [page, setPage] = useState(1)
17+
const [hasNextPage, setHasNextPage] = useState(true)
18+
19+
const loadPosts = useCallback(async () => {
20+
if (!hasNextPage) return
21+
22+
setIsLoading(true)
23+
const { data } = await getPosts({
24+
...searchParams,
25+
page: page.toString(),
26+
})
27+
28+
setPosts((prev) => [...prev, ...data?.data])
29+
setHasNextPage(data?.totalPages > page)
30+
setIsLoading(false)
31+
setPage((prev) => prev + 1)
32+
}, [searchParams, page])
33+
34+
return (
35+
<InfiniteScroll
36+
loading={isLoading}
37+
nextPage={loadPosts}
38+
>
39+
{posts?.map((post) => (
40+
<PostItem
41+
key={post.id}
42+
post={post}
43+
/>
44+
))}
45+
</InfiniteScroll>
46+
)
47+
}

apps/web/app/[lang]/(public)/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Metadata } from "next"
44
import { PostSkeleton } from "ui"
55

66
import Filter from "@/molecules/home/filter"
7-
import PostList from "@/molecules/post-list"
7+
import PostList from "@/molecules/posts/post-list"
88

99
export const metadata: Metadata = {
1010
title: "Next-forum - Share the best things",
@@ -16,7 +16,7 @@ export default async function Page() {
1616
<div>
1717
<Filter />
1818
<Suspense fallback={<PostSkeleton total={10} />}>
19-
<PostList containerClassName="mt-4" />
19+
<PostList />
2020
</Suspense>
2121
</div>
2222
)

0 commit comments

Comments
 (0)