ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

์ด์ „ ์ƒํ™ฉ : Tanstack Query ์ ์šฉ ์ค‘ undefined ๋ฐฉ์ง€

useEffect๋กœ ์ฒ˜๋ฆฌํ–ˆ๋˜ ์ด์ „ ๋กœ์ง์„ tanstack์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ปค์Šคํ…€ ํ›…์œผ๋กœ ๋บ๋‹ค.

์•„๋ž˜ ๋กœ์ง์€ formatted ๋กœ์ง์„ ์ œ์™ธํ•œ, supabase์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋ถ€๋ถ„๋งŒ ์ปค์Šคํ…€์œผ๋กœ ๋บ์„ ๋•Œ์˜ ๋กœ์ง์ด๋‹ค.

'use client';
import { Calendar, dateFnsLocalizer } from 'react-big-calendar';
import { format, parse, startOfWeek, getDay } from 'date-fns';
import { enUS } from 'date-fns/locale/en-US';
import { ko } from 'date-fns/locale/ko';
import { useState } from 'react';
import { CalendarEventType, PlansType } from '@/types/plans';
import { useGetCalendarPlans } from '@/hooks/useGetCalendarPlans';

// ๋กœ์ผ€์ผ(์ง€์—ญํ™”) ์„ค์ •
const locales = {
  'en-US': enUS, //๋ฏธ๊ตญ-์˜์–ด : ๋ฏธ๊ตญ์‹ ๋‚ ์งœ
  'ko-KR': ko, //ํ•œ๊ตญ-ํ•œ๊ธ€ : ํ•œ๊ตญ์‹ ๋‚ ์งœ
};

const localizer = dateFnsLocalizer({
  format,
  parse,
  startOfWeek,
  getDay,
  locales,
});

const MainCalendar = () => {
  const [events, setEvents] = useState<CalendarEventType[]>([]);

  const { data: plans, isPending, isError, error } = useGetCalendarPlans();

  const fetchEvents = async () => {
    const formatted = plans.map(
      (plan: PlansType): CalendarEventType => ({
        id: plan.plan_id,
        title: plan.title,
        start: new Date(plan.start_date),
        end: new Date(plan.end_date),
      })
    );
    setEvents(formatted);
  };

  if (isPending) {
    return <div>๋กœ๋”ฉ ์ค‘์ž…๋‹ˆ๋‹ค...</div>;
  }

  if (isError) {
    return <div>์บ˜๋ฆฐ๋” ์—๋Ÿฌ ๋ฐœ์ƒ : {error.message}</div>;
  }

  return (
    <div>
      <Calendar
        localizer={localizer}
        events={events} // ์—ฌ๊ธฐ์— ์ด๋ฒคํŠธ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
        startAccessor='start'
        endAccessor='end'
        style={{ height: 500 }}
      />
    </div>
  );
};

export default MainCalendar;

 

์ด๋•Œ, plans์˜ ๊ฐ’์ด undefined๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” eslint์˜ ๊ฐ์‹œ๊ฐ€ ์žˆ์—ˆ๋‹ค..!

์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ useQuery์— ํƒ€์ž…์„ ๋ช…์‹œํ•จ๊ณผ ํ•จ๊ป˜ initialData์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ดˆ๊ธฐ๊ฐ’์„ ๋นˆ ๋ฐฐ์—ด๋กœ ์ฃผ์—ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ›…์—์„œ data๋Š” ํ•ญ์ƒ PlansType[]์ด๊ณ , undefined๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.

useQuery<PlansType[]>({
  queryKey: ['calendarPlans'],
  queryFn: fetchPlans,
  initialData: [], // โœ… plans๋Š” ํ•ญ์ƒ [] ์ด์ƒ์˜ ๋ฐฐ์—ด์ด ๋จ
});

 

 

 

๋ฌธ์ œ ์ƒํ™ฉ : ์บ˜๋ฆฐ๋”์— ์ผ์ •์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Œ

ํ•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

์บ˜๋ฆฐ๋”์— ์ผ์ •์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š” ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

์–ด๋””์„œ๋ถ€ํ„ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ธ์ง€ ์ฝ˜์†”์„ ๋ชจ๋‘ ์ฐ์–ด๋ณด์•˜๋‹ค.

supabase์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง, useQuery์—์„œ ์ ์šฉํ•˜๋Š” ๋ถ€๋ถ„, ์บ˜๋ฆฐ๋” ์ปดํฌ๋„ŒํŠธ

๋”๋ณด๊ธฐ
๋”๋ณด๊ธฐ
๋”๋ณด๊ธฐ

์ฝ˜์†” ์ฐ์€ ๋ถ€๋ถ„๋“ค

// plans ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ - calendar ์‚ฌ์šฉ
export const getPlans = async (): Promise<PlansType[]> => {
  const { data: plans, error } = await supabase
    .from('plans')
    .select('plan_id, user_id, contacts_id, title, detail, priority, start_date, end_date');
  console.log('getPlans: plans', plans); โญ๏ธ
  if (error) {
    throw new Error(error.message);
  }
  return plans;
};
export const useGetCalendarPlans = () => {
  return useQuery<CalendarEventType[]>({
    queryKey: [QUERY_KEY.CALENDAR_PLANS],
    queryFn: async () => {
      const plans: PlansType[] = await getPlans(); // supabase์—์„œ plans ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
      console.log('useQuery: plans', plans); โญ๏ธ

      // ์บ˜๋ฆฐ๋”์— ์ ์šฉ๋˜๋„๋ก ๋ฐ์ดํ„ฐ ๊ฐ€๊ณตํ•˜๊ธฐ
      const events: CalendarEventType[] = plans.map((plan) => ({
        id: plan.plan_id,
        title: plan.title,
        start: new Date(plan.start_date),
        end: new Date(plan.end_date),
      }));
      console.log('useQuery: events', events); โญ๏ธ
      return events;
    },
    initialData: [], // undefined ์•„๋‹˜ ๋ช…์‹œ
    staleTime: 60 * 1000, // 1๋ถ„
  });
};
const MainCalendar = () => {
  const { data: events, isPending, isError, error } = useGetCalendarPlans();
  console.log('MainCalendar: events', events); โญ๏ธ

ํ•˜์ง€๋งŒ ๋นˆ ๋ฐฐ์—ด๋กœ ์ฐํžˆ๋ฉด์„œ ์บ˜๋ฆฐ๋”์—๋„ ์ผ์ •์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜๋‹ค.

 

์—ฌ๋Ÿฌ ์›์ธ์„ ์ฐพ์œผ๋ฉด์„œ ์‹œ๊ฐ„์ด ์ข€ ์ง€๋‚˜์ž, ๊ฐ‘์ž๊ธฐ ์ผ์ •๊ณผ ์ฝ˜์†”์ด ๋‹ค์‹œ ๋‚˜ํƒ€๋‚ฌ๋‹ค.

๋ญ˜๊นŒ.. ๋ญ˜๊นŒ...

๋ญ”๊ฐ€ ๋‚ด๊ฐ€ ์„ค์ •ํ•œ 1๋ถ„์˜ staleTime๊ณผ ๊ด€๋ จ์ด ์žˆ์„ ๊ฒƒ ๊ฐ™์•˜๋‹ค.

 

 

์˜ค๋ฅ˜ ์›์ธ ๋ฐ initialData ์šฉ๋„

์ฒ˜์Œ ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ์ฝ˜์†”์ด ์ฐํžˆ๋Š” ๋ชจ์Šต์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋นˆ ๊ฐ’(undefined)์ด ๋“ค์–ด์™”๋‹ค๊ฐ€ ๊ฐ’์ด ๋“ค์–ด์˜จ๋‹ค.

์›์ธ์€ ๋ฐ”๋กœ ์ด๊ฒƒ์ด์—ˆ๋‹ค.

initialData ๋ฅผ ๋นˆ ๋ฐฐ์—ด๋กœ ์„ค์ •ํ•ด๋‘์—ˆ์œผ๋‹ˆ, ์ฒ˜์Œ ๋นˆ ๋ฐฐ์—ด์ธ ๊ฐ’์„ ์บ์‹ฑํ•ด๋‘๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ ํ›„ staleTime(1๋ถ„)์ด ์ง€๋‚˜๋ฉด ์ƒˆ๋กญ๊ฒŒ ๊ฐ’์„ ํŽ˜์นญํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์ด๋‹ค.

 

์ฆ‰, initialData์˜ ์šฉ๋„๋Š” ์ƒˆ๋กœ์šด ๊ฐ’์„ ๋ฐ›์•„์˜ค๊ธฐ ์ „์— ๋น ๋ฅด๊ฒŒ ๊ฐ’์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.

์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ๋ฐ์ดํ„ฐ ์žˆ๊ฑฐ๋‚˜, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ ๋‚ด๋ ค์ฃผ๋Š” ๋“ฑ ์ง„์งœ ์ดˆ๊ธฐ๊ฐ’์„ ์œ„ํ•ด ์“ฐ์ด๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG
more
ยซ   2026/03   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
๊ธ€ ๋ณด๊ด€ํ•จ