diff --git a/src/components/CompletedDashboard.tsx b/src/components/CompletedDashboard.tsx index 0270c81..e58a3a4 100644 --- a/src/components/CompletedDashboard.tsx +++ b/src/components/CompletedDashboard.tsx @@ -7,15 +7,18 @@ import { Droppable } from 'react-beautiful-dnd'; import theme from '../styles/Theme/Theme'; import main2 from '../img/main2.png'; import { BlockListResDto } from '../types/PersonalBlock'; +import { useInView } from 'react-intersection-observer'; +import { useEffect } from 'react'; type Props = { // list: StatusPersonalBlock | undefined; list: BlockListResDto[]; id: string; dashboardId: string; + onLoadMore: () => void; }; -const CompletedDashboard = ({ list, id, dashboardId }: Props) => { +const CompletedDashboard = ({ list, id, dashboardId, onLoadMore }: Props) => { const navigate = useNavigate(); // const blocks = list.flatMap((item: StatusPersonalBlock) => item.blockListResDto); // const blocks = list?.blockListResDto; @@ -50,6 +53,17 @@ const CompletedDashboard = ({ list, id, dashboardId }: Props) => { navigate(`personalBlock/${blockId}`, { state: { highlightColor, progress, blockId } }); }; + // 세로 무한 스크롤 + const { ref: lastBlockRef, inView } = useInView({ + threshold: 0, // 마지막 블록이 0% 보였을 때를 감지 + }); + + useEffect(() => { + if (inView) { + onLoadMore(); // 부모 컴포넌트에 새로운 데이터 요청 + } + }, [inView]); + return (
@@ -67,7 +81,7 @@ const CompletedDashboard = ({ list, id, dashboardId }: Props) => { className="container" {...provided.droppableProps} > - {list?.map((block, index) => ( + {/* {list?.map((block, index) => ( { name={block.nickname ?? '이름 없음'} picture={block.picture ?? ''} /> - ))} + ))} */} + {list?.map((block, index) => { + const isLastBlock = index === list.length - 1; + return ( +
+ +
+ ); + })} {provided.placeholder} )} diff --git a/src/components/InProgressDashboard.tsx b/src/components/InProgressDashboard.tsx index ba1f4c9..7b16b6f 100644 --- a/src/components/InProgressDashboard.tsx +++ b/src/components/InProgressDashboard.tsx @@ -7,15 +7,18 @@ import { Droppable } from 'react-beautiful-dnd'; import theme from '../styles/Theme/Theme'; import main from '../img/main.png'; import { BlockListResDto } from '../types/PersonalBlock'; +import { useEffect } from 'react'; +import { useInView } from 'react-intersection-observer'; type Props = { // list: StatusPersonalBlock | undefined; list: BlockListResDto[]; id: string; dashboardId: string; + onLoadMore: () => void; }; -const InProgressDashboard = ({ list, id, dashboardId }: Props) => { +const InProgressDashboard = ({ list, id, dashboardId, onLoadMore }: Props) => { const navigate = useNavigate(); // const blocks = list.flatMap((item: StatusPersonalBlock) => item.blockListResDto); // const blocks = list?.blockListResDto; @@ -50,6 +53,17 @@ const InProgressDashboard = ({ list, id, dashboardId }: Props) => { navigate(`personalBlock/${blockId}`, { state: { highlightColor, progress, blockId } }); }; + // 세로 무한 스크롤 + const { ref: lastBlockRef, inView } = useInView({ + threshold: 0, // 마지막 블록이 0% 보였을 때를 감지 + }); + + useEffect(() => { + if (inView) { + onLoadMore(); // 부모 컴포넌트에 새로운 데이터 요청 + } + }, [inView]); + return (
@@ -67,7 +81,7 @@ const InProgressDashboard = ({ list, id, dashboardId }: Props) => { className="container" {...provided.droppableProps} > - {list?.map((block, index) => ( + {/* {list?.map((block, index) => ( { name={block.nickname ?? '이름 없음'} picture={block.picture ?? ''} /> - ))} + ))} */} + {list?.map((block, index) => { + const isLastBlock = index === list.length - 1; + return ( +
+ +
+ ); + })} {provided.placeholder} )} diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx index 7262a87..fe91f56 100644 --- a/src/pages/MainPage.tsx +++ b/src/pages/MainPage.tsx @@ -22,6 +22,7 @@ import { fetchTriggerAtom } from '../contexts/atoms'; import { getTeamDashboard } from '../api/TeamDashBoardApi'; import { TeamDashboardInfoResDto } from '../types/TeamDashBoard'; import 'react-toastify/dist/ReactToastify.css'; +import { flushSync } from 'react-dom'; export type TItemStatus = 'todo' | 'doing' | 'done' | 'delete'; const MainPage = () => { @@ -153,7 +154,6 @@ const MainPage = () => { } }, [page, fetchData]); - useEffect(() => {}, []); useEffect(() => { fetchBlockData(0); // 페이지가 로드될 때 처음으로 데이터를 불러옵니다. }, [dashboardId]); @@ -256,12 +256,15 @@ const MainPage = () => { const newList = Array.from(sourceList); const [movedItem] = newList.splice(source.index, 1); newList.splice(destination.index, 0, movedItem); - setColumns({ - ...columns, - [sourceKey]: { - ...columns[sourceKey], - list: newList, - }, + // ! 강제 렌더링 + flushSync(() => { + setColumns({ + ...columns, + [sourceKey]: { + ...columns[sourceKey], + list: newList, + }, + }); }); } else { const [movedItem] = sourceList.splice(source.index, 1);