๐Ÿ”– ์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์œผ๋กœ ์ฑ…๊ฐˆํ”ผ ํŽด๋“ฏ ๋ฐ์ดํ„ฐ ํƒ์ƒ‰ํ•˜๊ธฐ

zizonyoungjunยท2025๋…„ 1์›” 22์ผ
5
post-thumbnail

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ณด๋ฉด ๋งŽ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์„ ์ž์ฃผ ๋งˆ์ฃผ์น˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๊ฐ€์žฅ ๋จผ์ € ๋– ์˜ค๋ฅด๋Š” ํ•ด๊ฒฐ์ฑ…์ด ๋ฐ”๋กœ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด์ฃ . ํ•˜์ง€๋งŒ ์ „ํ†ต์ ์ธ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ ๊ธฐ๋ฐ˜์˜ ํŽ˜์ด์ง€๋„ค์ด์…˜์€ ๋ช‡ ๊ฐ€์ง€ ํ•œ๊ณ„์ ์„ ์•ˆ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฐ์ดํ„ฐ๊ฐ€ ์ค‘๊ฐ„์— ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ณ  ์žˆ๋˜ ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์ด ๋’ค์ฃฝ๋ฐ•์ฃฝ ๊ผฌ์—ฌ๋ฒ„๋ฆด ์ˆ˜ ์žˆ์ฃ  ๐Ÿ˜ตโ€๐Ÿ’ซ๐Ÿ’ซ

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ์ปค์„œ(Cursor) ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ ์ฑ…๊ฐˆํ”ผ์ฒ˜๋Ÿผ ํŠน์ • ์œ„์น˜๋ฅผ ํ‘œ์‹œํ•ด๋‘๊ณ , ๊ทธ ์ง€์ ๋ถ€ํ„ฐ ๋‹ค์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹์ธ๋ฐ์š”, ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์˜ ๊ฐœ๋…๊ณผ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ TanStack Query์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด๋ž€?

์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์€ ๋ฐ์ดํ„ฐ์˜ ํŠน์ • ์ง€์ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ทธ ์ดํ›„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ offset/limit ๋ฐฉ์‹์ด "5ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ ์ฃผ์„ธ์š”"๋ผ๊ณ  ์š”์ฒญํ•œ๋‹ค๋ฉด, ์ปค์„œ ๋ฐฉ์‹์€ "์ด ํ•ญ๋ชฉ ์ดํ›„์˜ ๋ฐ์ดํ„ฐ 20๊ฐœ๋ฅผ ์ฃผ์„ธ์š”"๋ผ๊ณ  ์š”์ฒญํ•˜๋Š” ์…ˆ์ด์ฃ . ๋งˆ์น˜ ๊ธด ๋ฌธ์„œ๋ฅผ ์ฝ๋‹ค๊ฐ€ ์ฑ…๊ฐˆํ”ผ๋ฅผ ๊ฝ‚์•„๋‘๊ณ , ๋‚˜์ค‘์— ๊ทธ ์ง€์ ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ฝ๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค ๐Ÿ”–

๊ฐ€๋ น, SNS ํ”ผ๋“œ๋‚˜ ๋ฌดํ•œ ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ•  ๋•Œ ์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กค์„ ๋‚ด๋ฆด ๋•Œ๋งˆ๋‹ค ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ณธ ๊ฒŒ์‹œ๋ฌผ์˜ ID๋ฅผ ์ปค์„œ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ ์ดํ›„์˜ ๊ฒŒ์‹œ๋ฌผ์„ ์š”์ฒญํ•˜๋Š” ์‹์ด์ฃ .

// ๊ธฐ์กด์˜ offset/limit ๋ฐฉ์‹
const fetchUsers = (page, limit) => {
  const offset = (page - 1) * limit;
  return db.users.findMany({
    skip: offset,
    take: limit
  });
};

// ์ปค์„œ ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜
const fetchUsers = (cursor, limit) => {
  return db.users.findMany({
    take: limit,
    cursor: {
      id: cursor
    },
    orderBy: {
      id: 'desc'
    }
  });
};

์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์˜ ์žฅ์ 

์ปค์„œ ๋ฐฉ์‹์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. offset ๋ฐฉ์‹์€ ์ค‘๊ฐ„์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋˜๋ฉด ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์ด ๋ฐ€๋ฆฌ๊ฑฐ๋‚˜ ์ค‘๋ณต๋  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ปค์„œ ๋ฐฉ์‹์€ ๊ฐ ๋ฐ์ดํ„ฐ ํ•ญ๋ชฉ์— ๋ถ€์—ฌ๋œ ๊ณ ์œ  ์‹๋ณ„์ž(๊ณ ์œ  ID๋‚˜ ํƒ€์ž„์Šคํƒฌํ”„ ๋“ฑ)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์˜ ๋ฌผ๋ฆฌ์ ์ธ ์œ„์น˜๋‚˜ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ์–ด๋„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ปค์„œ ๋ฐฉ์‹์€ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ํšจ์œจ์„ฑ์ด ๊ทน๋Œ€ํ™” ๋ฉ๋‹ˆ๋‹ค. PostgreSQL ํ™˜๊ฒฝ์—์„œ ์ง„ํ–‰ํ•œ ๋ฒค์น˜๋งˆํฌ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ๊ทธ ์ฐจ์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„ ๊ทธ๋ž˜ํ”„๋Š” 100๋งŒ ๊ฑด์˜ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ€์ƒ์œผ๋กœ, ํŽ˜์ด์ง€๋‹น 20๊ฐœ ํ•ญ๋ชฉ์„ ๊ธฐ์ค€์œผ๋กœ ๋‹ค์–‘ํ•œ ์œ„์น˜์—์„œ ๋ฐ˜๋ณต ์ธก์ •ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๊ทธ๋ž˜ํ”„์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, offset ๋ฐฉ์‹์€ ๋ ˆ์ฝ”๋“œ ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ• ์ˆ˜๋ก ์‘๋‹ต ์‹œ๊ฐ„์ด ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ 50๋งŒ ๊ฑด์„ ๋„˜์–ด๊ฐ€๋Š” ์ง€์ ๋ถ€ํ„ฐ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋šœ๋ ทํ•ด์ง€๋ฉฐ, 100๋งŒ ๊ฑด์— ๊ฐ€๊นŒ์›Œ์งˆ ๋•Œ๋Š” ํ‰๊ท  2์ดˆ ์ด์ƒ์ด ์†Œ์š”๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ์ปค์„œ ๋ฐฉ์‹์€ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ์™€ ๊ด€๊ณ„์—†์ด ์ผ๊ด€๋˜๊ฒŒ 50ms ์ด๋‚ด์˜ ์‘๋‹ต ์‹œ๊ฐ„์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ์ฐจ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ž‘๋™ ๋ฐฉ์‹์—์„œ ๊ธฐ์ธํ•ฉ๋‹ˆ๋‹ค. offset ๋ฐฉ์‹์—์„œ๋Š” ์ง€์ •๋œ offset๋งŒํผ์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์Šค์บ”ํ•œ ํ›„ ๊ฑด๋„ˆ๋›ฐ์–ด์•ผ ํ•˜์ง€๋งŒ, ์ปค์„œ ๋ฐฉ์‹์—์„œ๋Š” ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ํŠน์ • ์œ„์น˜์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ offset ๋ฐฉ์‹์€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰๋„ offset ํฌ๊ธฐ์— ๋น„๋ก€ํ•˜์—ฌ ์ฆ๊ฐ€ํ•˜๋Š”๋ฐ, 100๋งŒ ๊ฑด ๊ธฐ์ค€์œผ๋กœ ์ตœ๋Œ€ 128MB๊นŒ์ง€ ์ž„์‹œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ธก์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜์˜ ์žฅ์ ์„ ์ตœ๋Œ€ํ•œ์œผ๋กœ ํ™œ์šฉํ•˜๋ ค๋ฉด ํšจ๊ณผ์ ์ธ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ๊ฐ€ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ TanStack Query๊ฐ€ ๋“ฑ์žฅํ•˜๋Š”๋ฐ์š”, TanStack Query๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ปค์„œ ๊ธฐ๋ฐ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ›จ์”ฌ ๋” ํšจ๊ณผ์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฟผ๋ฆฌ ํ‚ค๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

TanStack Query๋Š” ์ฟผ๋ฆฌ ํ‚ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•ฉ๋‹ˆ๋‹ค. ๊ฒ€์ƒ‰์–ด, ํ•„ํ„ฐ, ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ, ๊ทธ๋ฆฌ๊ณ  ์ปค์„œ ์ •๋ณด๊นŒ์ง€ ํฌํ•จ๋œ ๋ฐฐ์—ด์„ ์ฟผ๋ฆฌ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ๊ฐ์˜ ๊ณ ์œ ํ•œ ๊ฒ€์ƒ‰ ์ƒํƒœ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์บ์‹œํ•  ์ˆ˜ ์žˆ์ฃ .

const queryKey = [
  "getSearch",// ๊ฒ€์ƒ‰ ๋„๋ฉ”์ธ
  debouncedQuery,// ๊ฒ€์ƒ‰์–ด
  filter,// ํ•„ํ„ฐ ์กฐ๊ฑด
  page,// ํ˜„์žฌ ํŽ˜์ด์ง€
  pageSize,// ํŽ˜์ด์ง€๋‹น ํ•ญ๋ชฉ ์ˆ˜
  cursor// ์ปค์„œ ์ •๋ณด
];

์ด๋ ‡๊ฒŒ ์„ค๊ณ„๋œ ์ฟผ๋ฆฌ ํ‚ค๋Š” ๋งˆ์น˜ ๋ฐ์ดํ„ฐ์˜ ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒ€์ƒ‰์–ด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜, ํ•„ํ„ฐ๋ฅผ ๋ฐ”๊พธ๊ฑฐ๋‚˜, ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค TanStack Query๋Š” ํ•ด๋‹นํ•˜๋Š” ์บ์‹œ๋ฅผ ์ •ํ™•ํžˆ ์ฐพ์•„๋‚ด์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ . ์ด๋Š” ๋ถˆํ•„์š”ํ•œ API ํ˜ธ์ถœ์„ ์ค„์ด๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”์™€ ์บ์‹ฑ ์ „๋žต

์ปค์„œ ๋ฐ์ดํ„ฐ๋Š” Zustand์™€ ๊ฐ™์€ ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ์™€ ๋งŒ๋‚˜๋ฉด ๋”์šฑ ๋น›์„ ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ์ปค์„œ ์ •๋ณด๋ฅผ ์ „์—ญ ์ƒํƒœ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด์„œ๋„, TanStack Query์˜ ์บ์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋™์‹œ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์ฃ .

const useSearchStore = create<SearchState>((set) => ({
  cursor: { preData: null, nextIndex: null },
  setCursor: (cursor) => set({
    preData: cursor?.preData || null,
    nextIndex: cursor?.nextIndex || null,
  }),
}));

// ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ ํ™œ์šฉ
const { data, isLoading } = useQuery({
  queryKey: ["getSearch", debouncedQuery, filter, page, pageSize, cursor],
  queryFn: () => getSearch({
    query: debouncedQuery,
    filter,
    page,
    pageSize,
    cursor,
  }),
  staleTime: 5 * ONE_MINUTE,
});

์ด ์ฝ”๋“œ์—์„œ๋Š” Zustand์™€ TanStack Query๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ปค์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Zustand๋Š” ์„œ๋ฒ„์—์„œ ๋ฐ˜ํ™˜๋œ ์ปค์„œ ์ •๋ณด๋ฅผ ์ „์—ญ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋™์ผํ•œ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. TanStack Query๋Š” ์ฟผ๋ฆฌ ํ‚ค์— ์ปค์„œ ์ •๋ณด๋ฅผ ํฌํ•จ์‹œ์ผœ, ๊ฐ ์ƒํƒœ๋ฅผ ๊ณ ์œ ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ณ  ์บ์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ค„์ž…๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ์บ์‹ฑ ์ „๋žต์˜ ๊ฒฐํ•ฉ์€ ๋ฐ์ดํ„ฐ ์š”์ฒญ์„ ์ตœ์ ํ™”ํ•˜๊ณ , ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

ํŽ˜์ด์ง€ ์ „ํ™˜ ์ตœ์ ํ™”ํ•˜๊ธฐ

์ปค์„œ ๊ธฐ๋ฐ˜์˜ ํŽ˜์ด์ง€ ์ „ํ™˜์€ ํŠน์ • ์ง€์ ์„ ๊ธฐ์ค€์œผ๋กœ ์ด์ „๊ณผ ๋‹ค์Œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋•Œ TanStack Query์˜ invalidateQueries๋ฅผ ํ™œ์šฉํ•˜๋ฉด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์„ ํƒ์ ์œผ๋กœ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const handlePage = (mode: "prev" | "next") => {
  const cursor = {
    curPage: page,
    preData,
    nextIndex,
  };

  if (mode === "next" && nextIndex) {
    setPage(page + 1);
    queryClient.invalidateQueries({
      queryKey: ["getSearch", searchParam, currentFilter, page + 1, 10,
        { ...cursor, preData: null }],
    });
  }
};

invalidateQueries๋Š” ํŠน์ • ์ฟผ๋ฆฌ ํ‚ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐฑ์‹ ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๋Š” ๋Œ€์‹ , ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ๋ถ€ํ•˜๋ฅผ ์ค„์ด๊ณ  ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑ๋œ ํŽ˜์ด์ง€ ์ „ํ™˜ ๋กœ์ง์€ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ๋นˆ๋ฒˆํ•œ ํ™˜๊ฒฝ์—์„œ๋„ ์•ˆ์ •์ ์œผ๋กœ ์ž‘๋™ํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ๋ถ€๋“œ๋Ÿฝ๊ณ  ๋น ๋ฅด๊ฒŒ ํŽ˜์ด์ง€๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. TanStack Query์™€ ์ปค์„œ ๊ธฐ๋ฐ˜ ์„ค๊ณ„๋Š” ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ์—์„œ๋„ ์ด๋Ÿฌํ•œ ์žฅ์ ์„ ๊ทน๋Œ€ํ™”ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์ปค์„œ ํŽ˜์ด์ง€๋„ค์ด์…˜๊ณผ TanStack Query ์ฝค๋น„๋Š” ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ํšจ๊ณผ์ ์ธ ํ•ด๊ฒฐ์ฑ…์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ offset ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ๊ฐ€์ง„ ์„ฑ๋Šฅ๊ณผ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ฉด์„œ๋„, TanStack Query์˜ ์บ์‹ฑ ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•ด ์„œ๋ฒ„ ๋ถ€ํ•˜๊นŒ์ง€ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์ฃ . ํŠนํžˆ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๊ณ  ๋ณ€๊ฒฝ๋˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฌดํ•œ ์Šคํฌ๋กค์ด๋‚˜ ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๋•Œ๋„, ์ปค์„œ ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜์€ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ณด์žฅํ•˜๋ฉด์„œ๋„ ๋ถ€๋“œ๋Ÿฌ์šด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ๊ณ„์‹œ๋‹ค๋ฉด, ์ปค์„œ ๋ฐฉ์‹์„ ๋„์ž… ํ•ด๋ณด๋Š” ๊ฑด ์–ด๋– ์‹ ๊ฐ€์š”? ํŽ˜์ด์ง€ ์ด๋™๋งˆ๋‹ค ๊นœ๋นก์ด๊ณ  ๋ฉˆ์ถ”์ง€ ์•Š๋Š” ๋กœ๋”ฉ ์Šคํ”ผ๋„ˆ์—์„œ ๋ฒ—์–ด๋‚˜์„œ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ์˜ ๊ฐˆํ”ผ๋ฅผ ์žก์„ ์ˆ˜ ์žˆ์„๊ฑฐ์˜ˆ์š” ๐Ÿฆพ

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2025๋…„ 1์›” 24์ผ

์™€ ์ญ‰์ญ‰ ์ฝํžˆ๋„ค์š” ์™œ ์ง€๊ธˆ๊นŒ์ง€ ๊ธ€์•ˆ์“ฐ์‹œ๊ตฌ... ๋งŽ์ด ๋ฐฐ์›Œ๊ฐ‘๋‹ˆ๋‹ค :)

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ