diff --git a/client/src/components/Chat/Chat.tsx b/client/src/components/Chat/Chat.tsx index b214727..115afcf 100644 --- a/client/src/components/Chat/Chat.tsx +++ b/client/src/components/Chat/Chat.tsx @@ -33,7 +33,7 @@ const Chat = () => { // socket.on(SOCKET_EVENT.SERVER_SENT, (data) => setChatList((prev) => [...prev, data])); socket.on(SOCKET_EVENT.SERVER_SENT_UNREAD, (data) => setChatList((prev) => [...prev, data])); socketRef.current = socket; - () => { + return () => { socket.disconnect(); }; }, [userId]); @@ -49,7 +49,7 @@ const Chat = () => { return ( - + ); diff --git a/client/src/components/Chat/ChatList/ChatList.tsx b/client/src/components/Chat/ChatList/ChatList.tsx index 1c1a8b1..a01e4cc 100644 --- a/client/src/components/Chat/ChatList/ChatList.tsx +++ b/client/src/components/Chat/ChatList/ChatList.tsx @@ -1,9 +1,15 @@ +import useChatHistoryQuery from "#hooks/queries/useChatQuery"; import { ChatResponse } from "#types/Chat"; -import { useEffect, useRef } from "react"; +import { Dispatch, SetStateAction, useEffect, useRef } from "react"; +import InfiniteScroll from "react-infinite-scroller"; +import { useParams } from "react-router-dom"; import styled from "styled-components"; +import { flexColumn } from "styles/flex"; import ChatItem from "../ChatItem/ChatItem"; const ChatListContainer = styled.div` + ${flexColumn({})}; + flex-direction: column-reverse; padding: 15px; width: 100%; height: inherit; @@ -17,10 +23,19 @@ const ChatListContainer = styled.div` interface ChatListProps { data: ChatResponse[]; + setChatList: Dispatch>; } -const ChatList = ({ data }: ChatListProps) => { +const ChatList = ({ data, setChatList }: ChatListProps) => { + const { id } = useParams(); const scrollRef = useRef(null); + const { data: chatHistory, fetchNextPage, hasNextPage } = useChatHistoryQuery({ recruitId: Number(id) }); + + useEffect(() => { + if (chatHistory?.pages?.at(-1)?.data === undefined) return; + // console.log(chatHistory?.pages?.at(-1)?.data); + setChatList((prev) => [...prev, ...(chatHistory?.pages?.at(-1)?.data || [])]); + }, [chatHistory]); useEffect(() => { scrollRef.current?.scrollTo(0, scrollRef.current.scrollHeight); @@ -28,9 +43,16 @@ const ChatList = ({ data }: ChatListProps) => { return ( - {data.map((el, idx) => ( - - ))} + fetchNextPage()} + hasMore={hasNextPage} + isReverse={true} + loader={
...loading
} + > + {data.map((el, idx) => ( + + ))} +
); }; diff --git a/client/src/hooks/queries/useChatQuery.ts b/client/src/hooks/queries/useChatQuery.ts new file mode 100644 index 0000000..e157ec8 --- /dev/null +++ b/client/src/hooks/queries/useChatQuery.ts @@ -0,0 +1,29 @@ +import { userState } from "#atoms/userState"; +import { ChatResponse } from "#types/Chat"; +import HttpResponse from "#types/dto/HttpResponse"; +import { useInfiniteQuery } from "@tanstack/react-query"; +import axios from "axios"; +import { useRecoilValue } from "recoil"; + +const useChatHistoryQuery = ({ recruitId }: { recruitId: number }) => { + const { userId } = useRecoilValue(userState); + return useInfiniteQuery( + ["chats", recruitId], + ({ pageParam = 1 }) => + axios + .get>("/chat", { + baseURL: import.meta.env.VITE_CHAT_API_URL, + params: { + recruitId, + userId, + page: pageParam, + }, + }) + .then((res) => res.data), + { + getNextPageParam: (lastPage, allPages) => (lastPage ? lastPage?.data.length > 0 && allPages.length + 1 : 1), + suspense: false, + }, + ); +}; +export default useChatHistoryQuery;