From 4212a3eb4d107e685337108fc0536954d8107fd2 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Thu, 22 Feb 2024 00:43:19 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20useObserver=20hook=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?,=20=EB=AC=B4=ED=95=9C=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/FriendListTemplate.tsx | 28 +++++++++++---- src/hooks/useObserver.ts | 35 +++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/hooks/useObserver.ts diff --git a/src/components/templates/FriendListTemplate.tsx b/src/components/templates/FriendListTemplate.tsx index d71a2a2..bb8dc73 100644 --- a/src/components/templates/FriendListTemplate.tsx +++ b/src/components/templates/FriendListTemplate.tsx @@ -6,13 +6,14 @@ import { useDisclosure, } from '@chakra-ui/react'; -import React, { useState } from 'react'; +import React, { useRef, useState } from 'react'; import { type SortLabel } from '@/types/common'; import { RadioButtonField, SortButton } from '../atoms'; import { FriendListItem } from '../organisms'; import { useGetFriendships } from '@/hooks/queries/friendship'; import type { FriendshipData, FriendshipSortType } from '@/types/friendship'; import { SuspenseFallback } from '.'; +import { useObserver } from '@/hooks/useObserver'; const SORT_TYPES: SortLabel[] = [ { label: '이름순', value: 'nickname' }, @@ -20,10 +21,24 @@ const SORT_TYPES: SortLabel[] = [ ]; const FriendListTemplate: React.FC = () => { + const bottom = useRef(null); const { isOpen, onOpen, onClose } = useDisclosure(); const [curSortType, setCurSortType] = useState(SORT_TYPES[0]); - const { data: friendsData } = useGetFriendships({ - sort: curSortType.value as FriendshipSortType, + const { data: friendsData, fetchNextPage: friendsNextPage } = + useGetFriendships({ + sort: curSortType.value as FriendshipSortType, + }); + + const onIntersect: IntersectionObserverCallback = ([entry]) => { + if (entry.isIntersecting) { + void friendsNextPage(); + console.log('next gogo'); + } + }; + + useObserver({ + target: bottom, + onIntersect, }); if (!friendsData?.pages[0].content) { @@ -31,7 +46,7 @@ const FriendListTemplate: React.FC = () => { } return ( - <> +
@@ -42,7 +57,7 @@ const FriendListTemplate: React.FC = () => {
-
+
{friendsData.pages.map((page) => page.content.map((ele: FriendshipData) => ( { )), )}
+
{ - +
); }; diff --git a/src/hooks/useObserver.ts b/src/hooks/useObserver.ts new file mode 100644 index 0000000..0264f25 --- /dev/null +++ b/src/hooks/useObserver.ts @@ -0,0 +1,35 @@ +import type { RefObject } from 'react'; +import { useEffect } from 'react'; + +export const useObserver = ({ + target, + onIntersect, + root = null, + rootMargin = '1px', + threshold = 0, +}: { + target: RefObject; + onIntersect: IntersectionObserverCallback; + root?: Element | Document | null; + rootMargin?: string; + threshold?: number | number[]; +}) => { + useEffect(() => { + let observer: IntersectionObserver | undefined; + + if (target?.current !== null) { + observer = new IntersectionObserver(onIntersect, { + root, + rootMargin, + threshold, + }); + observer.observe(target.current); + } + + return () => { + if (typeof observer !== 'undefined') { + observer.disconnect(); + } + }; + }, [target, rootMargin, threshold, onIntersect, root]); +};