채팅에서 투두리스트 저장 후 채팅 화면으로 이동했을 때 화면이 리렌더링 되지 않으면 ui가 업데이트 되지 않음
const fetchTodos = async (user_id: string): Promise<Todo[]> => {
const { data, error } = await supabase.from("todos").select("*").eq("user_id", user_id);
if (error) throw new Error(error.message);
return data ?? [];
};
const addTodo = async (todo: Partial<Todo>): Promise<Todo> => {
const { data, error } = await supabase.from("todos").insert(todo).select().single();
if (error) throw new Error(error.message);
return data as Todo;
};
const todosQuery = useQuery<Todo[], Error>({
queryKey: ["todos", user_id],
queryFn: () => fetchTodos(user_id)
});
const addTodoMutation = useMutation({
mutationFn: addTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["todos"] });
}
});
const saveChatTodoItems = async (supabase: SupabaseClient, sessionId: string, items: string[]) => {
const {
data: { user },
error: userError
} = await supabase.auth.getUser();
if (userError || !user) {
console.error("Error getting User Data", userError);
throw userError;
}
const todoToInsert = items.map((item) => ({
todo_id: uuid4(),
created_at: new Date().toISOString(),
todo_title: item,
todo_description: null,
user_id: user.id,
address: { lat: 0, lng: 0 },
event_datetime: dayjs().set("hour", 0).set("minute", 0).toISOString(),
is_done: false,
is_chat: true,
is_all_day_event: true
}));
const { data, error } = await supabase.from("todos").insert(todoToInsert).select();
if (error) {
console.error("Error saving chat todo items", error);
throw error;
}
return data;
};
saveChatTodoItems함수(서버 사이드)에서 addTodoMutation을 사용
-> 동일한 쿼리를 업데이트 시켜서 상태를 일정하게 유지할 수 있도록 함.
React 훅인 커스텀 훅은 컴포넌트나 커스텀 훅 내부에서만 사용 가능하기 때문에 일반 함수 또는 서버 사이드에서는 해당 훅을 사용할 수 없음.
queryClient.invalidateQueries({ queryKey: ["todos", userId] });
를 추가 const saveTodoMutation = useMutation({
mutationFn: async () => {
const response = await fetch(`/api/chat/${aiType}/${sessionId}`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ saveTodo: true, currentTodoList, isResetButton: false })
});
if (!response.ok) {
throw new Error("Failed to save todo list");
}
const data = await response.json();
return data;
},
onSuccess: () => {
const savedMessage = {
role: "assistant" as const,
content: "투두리스트 저장이 완료되었습니다. 저장된 내용을 투두리스트 페이지에서 확인해보세요!",
created_at: new Date().toISOString(),
showSaveButton: false
};
queryClient.setQueryData<MessageWithButton[] | undefined>(
[queryKeys.chat, aiType, sessionId],
(oldData): MessageWithButton[] | undefined => {
if (!oldData) return [savedMessage];
const updatedData = oldData.map((msg) => ({ ...msg, showSaveButton: false }));
return [...updatedData, savedMessage];
}
);
// 투두리스트 쿼리 무효화
queryClient.invalidateQueries({ queryKey: ["todos", userId] });
setCurrentTodoList([]);
toast.success("투두리스트 페이지로 이동하기", {
onClose: () => {
router.push("/todo-list");
}
});
},
onError: (error) => {
console.error("Error saving todo list :", error);
}
});