Convert useEffect-based task loading to React Query

- Replace useEffect data loading with useQuery hook in Usage.tsx
- Provides better caching, error handling, and loading states
- Simplifies modal state management logic
- Addresses PR comment requesting React Query usage for data loading

Fixes: Use React Query instead of useEffect for data loading
This commit is contained in:
Roo Code 2025-07-07 23:30:21 +00:00
parent 2c5d87fe95
commit 8860ceba71
2 changed files with 36 additions and 64 deletions

View file

@ -3,6 +3,7 @@
import { useState, useCallback, useEffect } from 'react';
import { useTranslations } from 'next-intl';
import { useUser, useAuth } from '@clerk/nextjs';
import { useQuery } from '@tanstack/react-query';
import { X, AlertCircle } from 'lucide-react';
import type { TaskWithUser } from '@/actions/analytics';
@ -36,14 +37,32 @@ export const Usage = ({
const t = useTranslations('Analytics');
const [viewMode, setViewMode] = useState<ViewMode>('tasks');
const [filters, setFilters] = useState<Filter[]>([]);
const [task, setTask] = useState<TaskWithUser | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [isLoadingTask, setIsLoadingTask] = useState(false);
const [showError, setShowError] = useState(!!error);
// Hash-based routing for deep linking
const { taskIdFromHash, setTaskHash } = useTaskHash();
// Use React Query for task loading instead of useEffect
const {
data: task,
isLoading: isLoadingTask,
error: taskError,
} = useQuery({
queryKey: ['getTaskById', taskIdFromHash, orgId, userId],
queryFn: () =>
getTaskById({
taskId: taskIdFromHash!,
orgId,
userId,
}),
enabled:
!!taskIdFromHash &&
!!isSignedIn &&
(orgId !== undefined || userId !== undefined),
retry: false,
});
const onAddFilter = useCallback((newFilter: Filter) => {
setFilters((currentFilters) => {
// Don't add if filter already exists
@ -55,67 +74,21 @@ export const Usage = ({
setViewMode('tasks');
}, []);
// Handle hash-based task loading
// Handle modal state based on hash and task data
useEffect(() => {
const loadTaskFromHash = async () => {
if (taskIdFromHash) {
// Wait for auth to be available before attempting to load task
if (!isSignedIn || (orgId === undefined && userId === undefined)) {
return; // Wait for auth to be ready
}
// Only load if we don't have the task or it's a different task
if (!task || task.taskId !== taskIdFromHash) {
setIsLoadingTask(true);
try {
const taskData = await getTaskById({
taskId: taskIdFromHash,
orgId,
userId,
});
if (taskData) {
setTask(taskData);
setIsModalOpen(true);
} else {
// Task not found or no permission, clear hash
setTaskHash(null);
setShowError(true);
}
} catch (error) {
console.error('Failed to load task:', error);
setTaskHash(null);
setShowError(true);
} finally {
setIsLoadingTask(false);
}
} else if (task && task.taskId === taskIdFromHash && !isModalOpen) {
// We have the right task but modal is closed, open it
setIsModalOpen(true);
}
} else if (!taskIdFromHash) {
// No hash, ensure modal is closed and task is cleared
if (isModalOpen) {
setIsModalOpen(false);
}
if (task) {
setTask(null);
}
// Always clear loading state when no hash
setIsLoadingTask(false);
}
};
loadTaskFromHash();
}, [
taskIdFromHash,
task,
orgId,
userId,
isModalOpen,
isSignedIn,
setTaskHash,
]);
if (taskIdFromHash && task) {
// Task loaded successfully, open modal
setIsModalOpen(true);
} else if (taskIdFromHash && taskError) {
// Task failed to load, clear hash and show error
console.error('Failed to load task:', taskError);
setTaskHash(null);
setShowError(true);
} else if (!taskIdFromHash) {
// No hash, ensure modal is closed
setIsModalOpen(false);
}
}, [taskIdFromHash, task, taskError, setTaskHash]);
useEffect(() => {
if (error) {
@ -148,8 +121,6 @@ export const Usage = ({
// Handle task selection with hash routing
const handleTaskSelect = useCallback(
(selectedTask: TaskWithUser) => {
setTask(selectedTask);
setIsModalOpen(true);
setTaskHash(selectedTask.taskId);
},
[setTaskHash],

1
comment.txt Normal file
View file

@ -0,0 +1 @@
@cte I'll convert the useEffect-based task loading to use React Query's useQuery hook. This will provide better caching, error handling, and loading states for the modal data loading. Working on this now.