Skip to content

Commit

Permalink
feat: 채팅 인피니트 스크롤 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
June1010 committed Dec 13, 2022
1 parent cbd76f9 commit a322a43
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 deletions.
4 changes: 2 additions & 2 deletions client/src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand All @@ -49,7 +49,7 @@ const Chat = () => {
return (
<ChatContainer>
<ChatRoomSummary id={Number(id)} />
<ChatList data={chatList} />
<ChatList data={chatList} setChatList={setChatList} />
<ChatInput sendMessage={sendMessage} />
</ChatContainer>
);
Expand Down
32 changes: 27 additions & 5 deletions client/src/components/Chat/ChatList/ChatList.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -17,20 +23,36 @@ const ChatListContainer = styled.div`

interface ChatListProps {
data: ChatResponse[];
setChatList: Dispatch<SetStateAction<ChatResponse[]>>;
}

const ChatList = ({ data }: ChatListProps) => {
const ChatList = ({ data, setChatList }: ChatListProps) => {
const { id } = useParams();
const scrollRef = useRef<HTMLDivElement>(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);
}, [data]);

return (
<ChatListContainer ref={scrollRef}>
{data.map((el, idx) => (
<ChatItem data={el} key={`${el.recruitId}_${idx}`} />
))}
<InfiniteScroll
loadMore={() => fetchNextPage()}
hasMore={hasNextPage}
isReverse={true}
loader={<div>...loading</div>}
>
{data.map((el, idx) => (
<ChatItem data={el} key={`${el.recruitId}_${idx}`} />
))}
</InfiniteScroll>
</ChatListContainer>
);
};
Expand Down
29 changes: 29 additions & 0 deletions client/src/hooks/queries/useChatQuery.ts
Original file line number Diff line number Diff line change
@@ -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<HttpResponse<ChatResponse[]>>("/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;

0 comments on commit a322a43

Please sign in to comment.