2.3 KiB
2.3 KiB
Task 6: Build React Query Hooks
Task ID: TASK-006 | Story: STORY-002 | Sprint: Sprint 1 Estimated Hours: 3h | Assignee: Frontend Developer 2 | Priority: P0 | Status: Not Started
Task Description
Create React Query hooks for Epic/Story/Task with query caching, mutations, and optimistic updates.
Implementation
File: src/hooks/useEpics.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { epicApiClient } from '../api/clients/EpicApiClient';
export const useEpics = (projectId: string) => {
return useQuery({
queryKey: ['epics', projectId],
queryFn: () => epicApiClient.getAll(projectId),
staleTime: 60000 // 1 minute
});
};
export const useCreateEpic = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: epicApiClient.create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['epics'] });
}
});
};
export const useUpdateEpic = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, dto }) => epicApiClient.update(id, dto),
onMutate: async ({ id, dto }) => {
// Optimistic update
await queryClient.cancelQueries({ queryKey: ['epics', id] });
const previous = queryClient.getQueryData(['epics', id]);
queryClient.setQueryData(['epics', id], dto);
return { previous };
},
onError: (err, vars, context) => {
queryClient.setQueryData(['epics', vars.id], context.previous);
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['epics'] });
}
});
};
export const useDeleteEpic = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: epicApiClient.delete,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['epics'] });
}
});
};
Acceptance Criteria
- useEpics/Stories/Tasks query hooks
- useCreate/Update/Delete mutation hooks
- Query cache invalidation working
- Optimistic updates for better UX
- Loading and error states handled
Deliverables
- useEpics.ts with 4 hooks
- useStories.ts with 4 hooks
- useTasks.ts with 4 hooks
- Unit tests (12+ tests)
Status: Not Started | Created: 2025-11-04