Gen hook
Generate React Query hooks for data operations (queries and mutations). Creates type-safe hooks for fetching, creating, updating, and deleting data with proper cache invalidation.From its SKILL.md
npx -y skills add Ramakrishnan24689/codeapps-toolkit --skill gen-hookAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.1 KB, as published. Nobody here has run it
Generate React Query Hooks
Generate React Query hooks for data fetching and mutations with proper cache management and TypeScript types.
What This Skill Does
- Creates query hooks for data fetching (use<Feature>, use<Feature>ById)
- Creates mutation hooks for data modification (useCreate<Feature>, useUpdate<Feature>, useDelete<Feature>)
- Implements proper query key hierarchy (factory pattern)
- Sets up cache invalidation after mutations
- Provides TypeScript types and error handling
- Includes optimistic updates pattern (advanced)
Usage
/gen-hook todos
/gen-hook accounts
/gen-hook userprofile
Template
This skill uses a comprehensive React Query template:
- templates/react-query-hooks.template.ts - Complete hooks with query key factory, cache management, and optimistic updates
How to use template: Read the template to understand the complete pattern, then generate adapted code based on the actual service layer you're integrating with.
Workflow
Step 1: Verify Service Layer Exists
Before generating hooks, ensure the service layer exists:
ls src/features/$ARGUMENTS[0]/services/*Service.ts
Read the service file to understand:
- Available methods (getTodos, createTodo, etc.)
- DTO types (CreateTodoDto, UpdateTodoDto)
- Domain model type (Todo)
Step 2: Read the React Query Template
Read templates/react-query-hooks.template.ts
Study the template structure:
- Query key factory pattern
- Query hooks with proper configuration
- Mutation hooks with cache invalidation
- Optimistic updates pattern
- TypeScript types
Step 3: Generate Hooks File Following Template Pattern
Create src/features/<feature>/hooks/use<Feature>.ts following the template structure.
React Query Hook Pattern (From Template)
Critical Pattern #1: Query Key Factory (From Template)
The template shows the query key factory pattern for hierarchical cache management:
// Query key factory - adapt to your feature name
const <feature>Keys = {
all: ['<feature>'] as const,
lists: () => [...<feature>Keys.all, 'list'] as const,
list: (filters?: Filters) => [...<feature>Keys.lists(), filters] as const,
details: () => [...<feature>Keys.all, 'detail'] as const,
detail: (id: string) => [...<feature>Keys.details(), id] as const,
};
Why this matters: Hierarchical keys allow precise cache invalidation.
Critical Pattern #2: Query Hooks with Proper Configuration
export const use<Features> = (filters?: <Feature>Filters) => {
return useQuery({
queryKey: <feature>Keys.list(filters), // Use factory
queryFn: () => <Feature>Service.get<Features>(filters),
staleTime: 5 * 60 * 1000, // 5 minutes
retry: 1,
});
};
export const use<Feature>ById = (id: string) => {
return useQuery({
queryKey: <feature>Keys.detail(id), // Use factory
queryFn: () => <Feature>Service.get<Feature>ById(id),
enabled: !!id, // ✅ Only run if ID exists
staleTime: 5 * 60 * 1000,
retry: 1,
});
};
Critical Pattern #3: Mutation Hooks with Cache Invalidation
export const useCreate<Feature> = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (dto: Create<Feature>Dto) =>
<Feature>Service.create<Feature>(dto),
onSuccess: () => {
// ✅ Invalidate all list queries
queryClient.invalidateQueries({ queryKey: <feature>Keys.lists() });
},
onError: (error) => {
console.error('Failed to create:', error);
},
});
};
export const useUpdate<Feature> = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, dto }: { id: string; dto: Update<Feature>Dto }) =>
<Feature>Service.update<Feature>(id, dto),
onSuccess: (_, variables) => {
// ✅ Invalidate both list and specific detail
queryClient.invalidateQueries({ queryKey: <feature>Keys.lists() });
queryClient.invalidateQueries({ queryKey: <feature>Keys.detail(variables.id) });
},
});
};
export const useDelete<Feature> = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => <Feature>Service.delete<Feature>(id),
onSuccess: (_, id) => {
queryClient.invalidateQueries({ queryKey: <feature>Keys.lists() });
queryClient.removeQueries({ queryKey: <feature>Keys.detail(id) }); // ✅ Remove from cache
},
});
};
Critical Pattern #4: Optimistic Updates (Advanced)
The template includes an optimistic update pattern for better UX:
export const useUpdate<Feature>Optimistic = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, dto }) => <Feature>Service.update<Feature>(id, dto),
onMutate: async ({ id, dto }) => {
// Cancel outgoing refetches
await queryClient.cancelQueries({ queryKey: <feature>Keys.detail(id) });
// Snapshot previous value
const previous = queryClient.getQueryData(<feature>Keys.detail(id));
// Optimistically update
queryClient.setQueryData(
<feature>Keys.detail(id),
(old) => old ? { ...old, ...dto } : old
);
return { previous, id };
},
onError: (err, variables, context) => {
// Rollback on error
if (context?.previous) {
queryClient.setQueryData(<feature>Keys.detail(context.id), context.previous);
}
},
onSettled: (_, __, variables) => {
// Always refetch to ensure consistency
queryClient.invalidateQueries({ queryKey: <feature>Keys.detail(variables.id) });
queryClient.invalidateQueries({ queryKey: <feature>Keys.lists() });
},
});
};
Step 4: Verify Against Template Checklist
Before completing, verify your generated hooks include:
- ✅ Query key factory with hierarchical structure
- ✅ All necessary imports from @tanstack/react-query
- ✅ Imports from service layer (service and types)
- ✅ Query hooks with proper staleTime and retry config
- ✅ Mutation hooks with cache invalidation in onSuccess
- ✅ Enabled flag in conditional queries (useById)
- ✅ Error handling in mutation onError
- ✅ TypeScript types for all functions
- ✅ Optional: Optimistic updates pattern included
Step 5: Test Hooks Integration
Verify hooks work with service layer:
# TypeScript check
npx tsc --noEmit
# Check imports resolve
grep "import.*Service" src/features/<feature>/hooks/use<Feature>.ts
Usage in Components (Examples)
function FeatureList() {
const { data: features, isLoading, error, refetch } = useFeatures();
const createFeature = useCreateFeature();
const updateFeature = useUpdateFeature();
const deleteFeature = useDeleteFeature();
if (isLoading) return <Spinner label="Loading..." />;
if (error) return <MessageBar intent="error">Failed to load</MessageBar>;
return (
<div>
{features?.map(feature => (
<Card key={feature.id}>{feature.name}</Card>
))}
</div>
);
}
Workflow
- Read service file to understand available methods
- Create hooks directory:
src/features/<feature>/hooks/ - Generate use<Feature>.ts with all hooks
- Add TypeScript imports and exports
- Validate TypeScript compilation
Output
✅ React Query hooks generated!
📁 Created: src/features/<feature>/hooks/use<Feature>.ts
🎣 Generated Hooks:
- use<Features>(): Query hook for fetching multiple
- use<Feature>ById(id): Query hook for single record
- useCreate<Feature>(): Mutation hook for creating
- useUpdate<Feature>(): Mutation hook for updating
- useDelete<Feature>(): Mutation hook for deleting
💡 Usage in components:
const { data, isLoading } = use<Features>();
const create = useCreate<Feature>();
await create.mutateAsync(newData);
Related Skills
- /gen-service: Generate service layer first
- /gen-component: Generate UI components using these hooks