๐ Task TODOLIST
- [x] ๋ถํ์ํ ์๋ฒ ์์ฒญ ์ค์ด๊ธฐ
- [x] TTV ์ค์ด๊ธฐ
๐จ TroubleShotting
TTV๋ฅผ ์ค์ด๊ณ ์ ์ด๊ธฐ์ ๊ฐ์ฅ ์ต์ ๋ฉ์ธ์ง 10๊ฐ๋ง ๊ฐ์ ธ์ค๋๋ก ํ๋ ์ผ๋ฌด์ง ์๋ง์.. ๊ฑฐ๊พธ๋ก ๋์๊ฐ๊ณ ์์๋ค.
๋ถํ์ํ ์๋ฒ์์ฒญ๊ณผ TTV๋ฅผ ์ค์ด์.
Why(์ด์ )?
- ์ด๊ธฐ์ allMsgs(์ต์ 10๊ฐ์ ๋ฉ์ธ์ง)๋ฅผ ์๋ฒ์์ ํธ์ถ ํ, ๊ฐ์ฅ ์ต์๋จ CSR ์ปดํฌ๋ํธ InitChat.tsx์ props๋ก ๋ฐ์์ setQueryData()๋ก ์ด๊ธฐ ๋ฉ์ธ์ง๋ฅผ ํธ์ถํจ์ผ๋ก์จ -> ํธ๊ธฐ๋กญ๊ฒ TTV๋ฅผ ์ค์ด๊ณ ์ ํ์ผ๋,
๋ค๋ฅธ ๊ณณ์์ useMsgsQuery() (= useSuspenseQuery)๋ฅผ ํธ์ถํ๊ณ ์์ด์ ์๋ฌด๋ฆฌ ์ต์๋จ ์ปดํฌ๋ํธ์์ set์ ํ๋ค ๋ค๋ฅธ ๊ณณ์์ useSuspenseQuery๋ก DB์ ์๋ก์ด ๋ฉ์ธ์ง๋ฅผ ์์ฒญํ๊ธฐ ๋๋ฌธ์, ํ๋ฉด์ focus out ํ๋ค๊ฐ ๋์์ค๋ฉด setQueryData๊ฐ ๋ฌด์ฐ๋๊ณ ์ ์ฒด ๋ฉ์ธ์ง๊ฐ ๋ ๋๋ง ๋๋ ์ด์๊ฐ ์์๋ค.
- ๋น์์๋ ๋๋ฆ ํด๊ฒฐํด๋ณด๊ณ ์,
"์ ๊ทธ๋ผ InitChat.tsx๊ฐ ์ต์๋จ ์ปดํฌ๋ํธ์ด๋๊น ์ ์ผ ๋จผ์ useSuspenseQuery๋ฅผ ํธ์ถํ๋ฉด, ๋ค๋ฅธ ๊ณณ์์ ํธ์ถํ๋ useSuspenseQuery๋ InitChat.tsx์์ ํธ์ถํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ๋ค ์ฐ๊ฒ ๊ตฌ๋!"
ํ๊ณ InitChat.tsx์์ ํธ์ถํ์๋ค.
- ๊ทธ๋ฐ๋ฐ, ๊ทธ๋ ๊ฒ ๋๋ฉด ์๋ฒ์์๋ ์ต๊ทผ 10๊ฐ๋ฅผ ํธ์ถํด์ ํด๋ผ์ด์ธํธ์ ๋๊ธฐ๊ณ , ํด๋ผ์ด์ธํธ(InitChat.tsx)์์๋ useMsgsQuery()๋ฅผ ํธ์ถํด๋ฒ๋ฆฌ๋ ๊ผด๋ก ์๋ฒ์ ๋ ๋ฒ ํธ์ถํ๊ฒ ๋๋๋ฐ ์ด๊ฒ ๋ฐ๋ก ๋ญ ํผํ๋ ค๋ค๊ฐ ๋ฅ์ ๋ฐ์...์ํฉ์ด์๋ค.
How(๊ณผ์ )?
(1) 1์ฐจ ์ํ์ฐฉ์ค
ok. ๊ทธ๋ฌ๋ฉด ์๋ฒ์์ ๋๊ฒจ์ฃผ๋ ์ต์ 10๊ฐ ๋ฉ์ธ์ง๋ฅผ ์บ์๋ฐ์ดํฐ๋ก ์ฐ๊ณ , Inichat.tsx๋ฅผ ํฌํจํ messages๋ฅผ ํ์๋ก ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ์์ useMsgsQuery() ๋์ -> getQueryData()๋ก ๋ค ๋ฐ๊ฟ๋ณด์.
๊ทธ๋ฐ ๋ค์, ๋ฉ์ธ์ง๊ฐ ์๋ก ์ถ๊ฐ๋๋ฉด(= payload๊ฐ ์ถ๊ฐ๋๋ฉด)
1) invalidateQueries๋ฅผ ํ๊ณ ,
2) ๊ทธ๋ผ DB์ ๋ฐ์ดํฐ๊ฐ ์
๋ฐ์ดํธ ๋ ํ
๋
3) ๊ทธ๊ฑธ ๋ค์ getQueryData๋ฅผ ํ ๋ค, ์ ์ ๊ฐ ์ด์ ์ ๋ณด๋๋๋ก ๋ ๋๋ง ํ๊ธฐ ์ํด์ ๊ฐ๊ณตํด์ setQueryData()๋ฅผ ํด์ผ๊ฒ ๋ค!
๋ ์ผ๋ฌด์ง ๊ณํ์ ์ง๋ณธ ๊ฒฐ๊ณผ,
async (payload) => {
if (payload) {
1) await queryClient.invalidateQueries({ queryKey: [MSGS_QUERY_KEY, chatRoomId] });
2) const includingNew: Message[] | undefined = queryClient.getQueryData([MSGS_QUERY_KEY, chatRoomId]);
const lastIdx =
messages?.length && includingNew?.map((i) => i.message_id).indexOf(messages[0].message_id);
messages &&
includingNew &&
3) (await queryClient.setQueryData(
[MSGS_QUERY_KEY, chatRoomId],
[...includingNew].slice(lastIdx ?? 0, includingNew.length)
));
invalidateQueries๋ฅผ ํจ์๋ devTools๋ก ํ์ธํ ์บ์๋ฐ์ดํฐ๊ฐ ์
๋ฐ์ดํธ ๋์ง ์๋ ํ์ ๋ฐ์..
=> ์ด๋ก์จ ์๊ฒ๋ ์
: invalidateQueries๋ useQuery/useSuspenseQuery๊ฐ ์์ด๋ ์บ์๋ฐ์ดํฐ๋ฅผ ๋ฌดํจํํ๊ณ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค์ง ๋ชป ํ๋ค..
(2) 2์ฐจ ์ํ์ฐฉ์ค
- ๊ทธ๋ ๋ด invalidateQueries๋ฅผ ์์ฐ๊ณ (useSuspenseQuery๋ฅผ ์ด๋ป๊ฒ๋ ์์ฐ๊ฒ ๋ค๋ ์ด์ํ ๊ณ ์ง...) ๊ทธ๋ฅ fetchํ๋ ํจ์๋ฅผ ๋ ๊ฒ์ผ๋ก ์จ๋ณผํ
๋ค!
async (payload) => {
if (payload) {
const includingNew = await fetchMsgs(chatRoomId) --> ๋ ๊ฒ์ fetch
console.log("includingNew =>", includingNew)
const lastIdx =
messages?.length && includingNew?.map((i) => i.message_id).indexOf(messages[0].message_id);
messages &&
includingNew &&
(await queryClient.setQueryData(
[MSGS_QUERY_KEY, chatRoomId],
[...includingNew].slice(lastIdx ?? 0, includingNew.length)
));
const newArr = messages &&
includingNew &&
(await queryClient.setQueryData(
[MSGS_QUERY_KEY, chatRoomId],
[...includingNew].slice(lastIdx ?? 0, includingNew.length)
));
console.log("newArr =>", newArr)
}
}
)
50์ ์๋ก ์ถ๊ฐํ๋ฉด ์ด๋ฒ์๋ devTools์ ์บ์๋ฐ์ดํฐ์ setQueryDataํ ๋ฐํ๊ฐ์ ์ฝ์๋ก ์ฐ์ด๋ณด๋ ๋ ๋ค ์ ์
๋ฐ์ดํธ ๋จ!
ํ์ง๋ง, re-๋ ๋๋ง์ด ๋์ง ์์ใ
ใ
์์ธ์ ์์ useQuery๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ค์ -> ๋ชจ๋ getQueryData()๋ก ๋ฐ๊พธ์๋ค๊ณ ํ๋๋ฐ, getQueryData()๋ ๋ณ๊ฒฝ๋ ์บ์๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ํ์ง ๋ชปํ์ฌ re-๋ ๋๋ง์ ์ผ์ผํค์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ด์๋ค..
=> ์ด ์ํ์ฐฉ์ค๋ค๋ก ๋ฐฐ์ด ์
: invalidateQuries์ setQueryData, getQueryData ๋ชจ๋ useQuery/UseSuspenseQuery ์์ด ๋จ๋
์ผ๋ก๋ ์บ์๋ฐ์ดํฐ๋ฅผ ์์ ์
๋ฐ์ดํธ ํ์ง ๋ชปํ๊ฑฐ๋, ์
๋ฐ์ดํธ ํด๋ re-๋ ๋๋ง์ ์ผ์ผํค์ง ๋ชปํ์ฌ ๋ฌด์ฉ์ง๋ฌผ์ด ๋๋ค..
what(๊ฒฐ๊ณผ) ?
๊ทธ๋ฌ๋ค ๋ฌธ๋.. ์์ ์ prefetch๋ก dehydration ํด์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ก ๋๊ฒผ๋ ๊ฒ์ด ์๊ฐ๋ฌ๋ค.
๊ทธ๋ ์ง๋ง ์ฌ์ค ์์ฌ์ ๋๋ค.
'์ด๊ฒ๋ ์๋ฒ์์ prefetch ํ์ง๋ง, ์ด์จ๋ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์ useSuspenseQuery๋ก ๋ถ๋ฅด๋ฉด, ๋ ๋ฒ ํธ์ถ๋๋ ๊ฑฐ ์๋๊ฐ?'
๊ฒฐ๊ณผ๋ ์๋์๋ค. prefetch + dehydration ํด์ hydration ์ ์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ๋ฅผ ๋๊ธด ๋ค, ์ปดํฌ๋ํธ์์ useSuspense๋ฅผ ํด๋ prefetchํ ๊ฒฐ๊ณผ(์ต์ 10๊ฐ ๋ฐ์ดํฐ)๋ฅผ ์ฌ์ฉํ๊ณ (์ฌํธ์ถ X)
useSuspenseQuery์ ๋ฐํ๊ฐ์ด ์จ์ ํ ์ต์ 10๊ฐ์ ๋ฐ์ดํฐ๋ก ์ ๋ฐํ๋์๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ฌ ๋์ ์ต์ข ์ฝ๋๋..
const ChatPage = async ({ params }: { params: { chatroom_id: string } }) => {
const chatRoomId = params.chatroom_id;
const supabase = serverSupabase();
const {
data: { user }
} = await supabase.auth.getUser();
const prefetchMsgs = async () => {
const { from, to } = getFromTo(0, ITEM_INTERVAL);
const { data: allMsgs, error } = await supabase
.from('messages')
.select('*')
.eq('chatting_room_id', chatRoomId)
.range(from, to)
.order('created_at', { ascending: false });
if (error || !allMsgs) {
console.error(error.message);
} else {
return allMsgs;
}
};
const queryClient = new QueryClient();
await queryClient.prefetchQuery({ -----> (1)
queryKey: [MSGS_QUERY_KEY, chatRoomId],
queryFn: prefetchMsgs
});
return (
<main>
<HydrationBoundary state={dehydrate(queryClient)}> ----> (2)
<Suspense fallback={<ChatLoading />}>
<div className="relative flex flex-row">
<InitChat user={user} chatRoomId={chatRoomId} />
<div className="flex lg:flex-row w-full max-sm:flex-col justify-center mx-auto">
<section className="lg:flex lg:max-w-96 max-sm:absolute max-sm:z-50 max-sm:bg-white ">
<SideBar chatRoomId={chatRoomId} />
</section>
<section className="w-full max-w-xl max-h-[calc(100vh-90px)] min-h-[36rem] relative">
<div className="absolute top-0 left-0">
<SideBarButton />
</div>
<div className="h-full border rounded-md flex flex-col relative ">
<ChatHeader chatRoomId={chatRoomId} />
<Suspense>
<ChatList user={user} chatRoomId={chatRoomId} />
<ChatInput />
</Suspense>
</div>
</section>
</div>
</div>
</Suspense>
</HydrationBoundary>
</main>
);
};
chatPage > InitChat.tsx
const InitChat = ({ user, chatRoomId }: { user: User | null; chatRoomId: string }) => {
const allMsgs = useMsgsQuery(chatRoomId);