TIL

2024.04.04 TIL #์ฑ„ํŒ… #์ด์ „๋ฉ”์„ธ์ง€ _๋”๋ณด๊ธฐ

inz1234 2024. 5. 3. 01:37

๐Ÿ“Œ Task TODOLIST

- [x] ์ด์ „ ๋ฉ”์„ธ์ง€ ๋”๋ณด๊ธฐ ๊ธฐ๋Šฅ 

- [x] ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ

- [x] ๊ฐ€์ ธ์˜ฌ ๋ฉ”์„ธ์ง€๊ฐ€ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์€ ๋ฉ”์„ธ์ง€์˜ ๊ฐฏ์ˆ˜๋ณด๋‹ค ์ ์œผ๋ฉด? ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ ์•ˆ๋ณด์ด๊ฒŒ 

 


โœจ๊ฐœ๋ฐœ ๋‚ด์šฉ

1. ์ด์ „ ๋ฉ”์„ธ์ง€ ๋”๋ณด๊ธฐ ๊ธฐ๋Šฅ

Why ?

  ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  ๋ฉ”์„ธ์ง€๋ฅผ ๋‹ค ๋ถˆ๋Ÿฌ์˜ค๋ฉด ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ดˆ๊ธฐ์— ๋ถˆ๋Ÿฌ์™€์•ผ ํ•ด์„œ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์‹œ๊ฐ„์ด ๊ธธ์–ด์งˆ ๊ฑฐ๋ผ๊ณ  ํŒ๋‹จ.

How ?

  (1) ์•„์˜ˆ ์ฒ˜์Œ์—๋Š” 11๊ฐœ์˜ ๋ฉ”์„ธ์ง€๋งŒ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์„œ CSR ํŽ˜์ด์ง•์—์„œ hydrationํ•จ์œผ๋กœ์จ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์†๋„ ์ค„์ด๊ธฐ

  (2) ๊ทธ ์ดํ›„ ์ด์ „ ๋ฉ”์„ธ์ง€๋ฅผ ๋” ๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด, ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๊ธฐ -> ์ด์ „ 10๊ฐœ์˜ ๋ฉ”์„ธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

what

๋ถˆ๋Ÿฌ์˜ฌ ๋ฉ”์„ธ์ง€ ์ˆ˜ ์ƒ์ˆ˜ํ™”

export const ITEM_INTERVAL = 10;

๋”๋ณด๊ธฐ ํšŸ์ˆ˜์— ๋”ฐ๋ฅธ ๋ถˆ๋Ÿฌ์˜ฌ ๋ฉ”์„ธ์ง€์˜ range๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” utility ํ•จ์ˆ˜ getFromTo  ์ƒ์„ฑ

export const getFromTo = (loadCount: number, idx: number) => {
  const from = loadCount * (idx + 1);
  const to = from + idx;

  return { from, to };
};

 

์ดˆ๊ธฐ ์„œ๋ฒ„์‚ฌ์ด๋“œ ์ปดํฌ๋„ŒํŠธ์ธ chat/page.tsx ์—์„œ ๊ฐ€์žฅ ์ตœ์‹  10๊ฐœ์˜ ๋ฉ”์„ธ์ง€๋งŒ ์š”์ฒญํ•˜์—ฌ, InitChat.tsx ๋ผ๋Š” CSR ์ปดํฌ๋„ŒํŠธ์— props๋กœ ๋„˜๊ฒจ์คŒ 

const ChatPage = async ({ params }: { params: { chatroom_id: string } }) => {
  const chatRoomId = params.chatroom_id;
  const supabase = serverSupabase();
  const {
    data: { user }
  } = await supabase.auth.getUser();
  const { from, to } = getFromTo(0, ITEM_INTERVAL);
  const { data: allMsgs } = await supabase
    .from('messages')
    .select('*')
    .eq('chatting_room_id', chatRoomId)
    .range(from, to)
    .order('created_at', { ascending: false });

  return (
    <Suspense fallback={<ChatLoading />}>
      <div className="relative flex flex-row">
        <InitChat user={user} chatRoomId={chatRoomId} allMsgs={allMsgs ?? []} /> --> CSR ์ปดํฌ๋„ŒํŠธ

 

InitChat.tsx ํŒŒ์ผ์—์„œ๋Š” ๊ฐ€์ ธ์˜จ ๋ฉ”์„ธ์ง€๋“ค๋กœ ์ดˆ๊ธฐ ์ฟผ๋ฆฌ๋ฐ์ดํ„ฐ๋กœ setQueryData()

  if (allMsgs) {
        queryClient.setQueryData([MSGS_QUERY_KEY, chatRoomId], [...allMsgs].reverse());
        }

 

2. ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ + ๊ฐ€์ ธ์˜ฌ ๋ฉ”์„ธ์ง€๊ฐ€ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์€ ๋ฉ”์„ธ์ง€์˜ ๊ฐฏ์ˆ˜๋ณด๋‹ค ์ ์œผ๋ฉด? ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ ์•ˆ๋ณด์ด๊ฒŒ 

why?

๊ฐ€์ ธ์˜ฌ ๋ฉ”์„ธ์ง€๊ฐ€ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์€ ๋ฉ”์„ธ์ง€ ๊ฐฏ์ˆ˜๋ณด๋‹ค ๋งŽ์œผ๋ฉด ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ ๋ณด์—ฌ์ฃผ๊ณ , ์ ์œผ๋ฉด ์•ˆ ๋ณด์—ฌ์ค˜์•ผ ํ•˜๋‹ˆ๊นŒ

= ๋ณ€ํ•˜๋Š” ์ƒํƒœ๊ตฌ๋‚˜ = state ๋งŒ๋“ค๊ธฐ

์ฒ˜์Œ์— ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ์ดํ„ฐ๋ถ€ํ„ฐ ์ ์šฉ์ด ๋˜์–ด์•ผ ํ•˜๋‹ˆ๊นŒ ์ดˆ๊ธฐ ๋ฉ”์„ธ์ง€๋ฅผ setQueryData()๋ฅผ ์‚ฌ์šฉํ•˜๋Š”  InitChat.tsx์—์„œ๋„ ์“ฐ์ด๊ณ ,  ์‹ค์ œ๋กœ ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋”๋ณด๊ธฐ๊ฐ€ ๋˜๋Š” LoadChatMore.tsx์—์„œ๋„ ์“ฐ์ด๋‹ˆ ์ „์—ญ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜์ž.

=> zustand store ์‚ฌ์šฉ

export const chatStore = create<chatState>()((set) => ({
  chatRoomId: null,
  hasMore: false,  ---> ์ด๊ฒƒ
  chatState: true,
  isRest: true,
  searchMode: false,
  imgs: [],
  onlineUsers: [],

  setChatRoomId: (chatRoomId) => set({ chatRoomId }),
  setHasMore: (hasMore) => set({ hasMore }),  ---> ๋”๋ณด๊ธฐํ• ์ง€ ๋ง์ง€ setStateํ•˜๋Š” ํ•จ์ˆ˜
  setChatState: (isActive) => set({ chatState: isActive }),
  setisRest: (isRest) => set({ isRest }),
  setSearchMode: () => set((state) => ({ searchMode: !state.searchMode })),
  setImgs: (imgs) => set({ imgs }),
  setOnlineUsers: (onlineUsers) => set({ onlineUsers })
}));

 

How?

- ๊ธฐ๋ณธ์ ์œผ๋กœ ์ดˆ๊ธฐ์— ๋ฉ”์„ธ์ง€๋ฅผ ๊ฐ€์ ธ์™”๋Š”๋ฐ ๋”๋ณด๊ธฐ ํ•ด์„œ ๊ฐ€์ ธ์˜ฌ ๊ฐฏ์ˆ˜(11๊ฐœ) ๋ณด๋‹ค ์ ์œผ๋ฉด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์„ ์ˆจ๊ฒจ์•ผ ํ•จ

 if (allMsgs) {
        queryClient.setQueryData([MSGS_QUERY_KEY, chatRoomId], [...allMsgs].reverse());
        setHasMore(allMsgs.length >= ITEM_INTERVAL + 1);
      }

์ฒ˜์Œ์— ๊ฐ€์ ธ์˜จ ๋ฉ”์„ธ์ง€(allMsgs)๊ฐ€ ๋ถˆ๋Ÿฌ์˜ฌ ๋ฉ”์„ธ์ง€(ITEM_INTERVAL + 1) ๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผ๋งŒ ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์ด ๋ณด์ด์ž.

 

- ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ƒˆ๋กœ์šด ๋ฉ”์„ธ์ง€๋“ค์„ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•˜๊ณ , ๊ฐ€์ ธ์˜จ ๋ฉ”์„ธ์ง€๊ฐ€ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์‹ถ์—ˆ๋˜ ๋ฉ”์„ธ์ง€๋ณด๋‹ค ์ ์œผ๋ฉด setHasMore(false)๋กœ!

   if (newMsgs.length < ITEM_INTERVAL + 1) {
        setHasMore(false);
        }

 

 

๐Ÿšจ  TroubleShotting

1. ๊ทธ๋Ÿฐ๋ฐ! ์ด๋ ‡๊ฒŒ ํ–ˆ๋”๋‹ˆ, ์ฒ˜์Œ ๋ Œ๋”๋ง ์‹œ์—๋Š” ์ตœ์‹  10๊ฐœ๊ฐ€ ์ž˜ ๋ Œ๋”๋ง ๋˜์—ˆ์ง€๋งŒ ๊ทธ ๋’ค์— ์–ด๋””๋ฅผ ๊ฐ”๋‹ค ์˜ค๊ฑฐ๋‚˜ focus out ํ›„ ๋‹ค์‹œ ๋Œ์•„์˜ค๋‹ˆ ์ „์ฒด ๋ฉ”์„ธ์ง€๊ฐ€ ์™€๋‹ค๋‹ค ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ!

why? 

์ดˆ๊ธฐ์—๋Š” setQueryData()๋ฅผ ํ–ˆ์ง€๋งŒ useSuspenseQuery๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— focus out ํ›„ ๋Œ์•„์˜ค๋ฉด  useSuspenseQuery๊ฐ€ ์‹คํ–‰๋˜๋ฉด์„œ ์ „์ฒด ๋ฉ”์„ธ์ง€๋ฅผ ๋‹ค์‹œ fetch.

 

What?

export const useMsgsQuery = (chatRoomId: string) => {
  const { data } = useSuspenseQuery({
    queryKey: [MSGS_QUERY_KEY, chatRoomId],
    queryFn: () => fetchMsgs(chatRoomId),
    refetchOnMount: false,
    refetchOnReconnect: false,
    refetchOnWindowFocus: false
  });
  return data;
};

=> ์ง์ ‘ ๋”๋ณด๊ธฐ or invalidate ํ•ด์•ผ๋งŒ ์ด์ „ ๋ฉ”์„ธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์ž๋™ refetch๋˜๋Š” ์˜ต์…˜ ๋ชจ๋‘ false

 

๐Ÿ“š ๋ ˆํผ๋Ÿฐ์Šค

setQueryData()

https://tanstack.com/query/latest/docs/reference/QueryClient#queryclientsetquerydata