Skip to content

Commit

Permalink
feat: useObserver hook 추가, 무한 스크롤 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeseon-han committed Feb 21, 2024
1 parent 9f6f608 commit 4212a3e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
28 changes: 22 additions & 6 deletions src/components/templates/FriendListTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,47 @@ 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' },
{ label: '등록순', value: 'createdAt' },
];

const FriendListTemplate: React.FC = () => {
const bottom = useRef<HTMLDivElement>(null);
const { isOpen, onOpen, onClose } = useDisclosure();
const [curSortType, setCurSortType] = useState<SortLabel>(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) {
return <SuspenseFallback />;
}

return (
<>
<div className="h-screen flex flex-col">
<div className="mt-[57px] fixed w-screen max-w-[480px]">
<div className="h-[1px] mt-[-1px] bg-gray1" />
<div className="flex justify-between px-[20px] py-[18px] bg-white body1-medium">
Expand All @@ -42,7 +57,7 @@ const FriendListTemplate: React.FC = () => {
</div>
</div>

<div className="pt-[128px] px-[20px]">
<div className="flex flex-1 overflow-y-auto pt-[128px] px-[20px]">
{friendsData.pages.map((page) =>
page.content.map((ele: FriendshipData) => (
<FriendListItem
Expand All @@ -53,6 +68,7 @@ const FriendListTemplate: React.FC = () => {
)),
)}
</div>
<div ref={bottom} />

<Modal
onClose={onClose}
Expand Down Expand Up @@ -85,7 +101,7 @@ const FriendListTemplate: React.FC = () => {
</ModalBody>
</ModalContent>
</Modal>
</>
</div>
);
};

Expand Down
35 changes: 35 additions & 0 deletions src/hooks/useObserver.ts
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement>;
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]);
};

0 comments on commit 4212a3e

Please sign in to comment.