

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456# Guidelines for Query Hooks78## Purpose and Overview9Query hooks abstract data fetching operations using TanStack Query to provide optimized caching, loading states, error handling, and refetching strategies. They connect UI components to the data access layer, making components cleaner and more focused on presentation rather than data fetching logic.1011## Structure and Organization1213### Query Hooks Module Structure14```15src/16├── hooks/ # Shared hooks module17│ └── query/ # Shared query hooks18│ └── [entity]/19│ ├── use-[entity]-query.ts # Read single entity20│ ├── use-search-[entity]s-query.ts # Search with regular pagination21│ └── use-search-[entity]s-infinite-query.ts # Search with infinite scroll22└── features/23 └── [feature-name]/24 └── _hooks/ # Feature-specific hooks25 └── query/ # Feature-specific query hooks26 └── [entity]/27 ├── use-[entity]-query.ts28 ├── use-search-[entity]s-query.ts29 └── use-search-[entity]s-infinite-query.ts30```3132## Naming Conventions3334### Files35- `use-[entity]-query.ts`: For querying a single entity by ID36- `use-search-[entity]s-query.ts`: For searching entities with regular pagination37- `use-search-[entity]s-infinite-query.ts`: For searching entities with infinite scroll3839### Functions40- `use[Entity]Query`: For querying a single entity41- `useSearch[Entity]sQuery`: For searching entities with regular pagination42- `useSearch[Entity]sInfiniteQuery`: For searching entities with infinite scroll4344### Types45- `Use[Entity]QueryArgs`: Arguments for single entity query46- `UseSearch[Entity]sQueryArgs`: Arguments for regular search query47- `UseSearch[Entity]sInfiniteQueryArgs`: Arguments for infinite search query4849## Implementation Guidelines5051### Query Hooks52- Use TanStack Query's `useQuery` hook for regular queries53- Use `useInfiniteQuery` for paginated/infinite scroll queries54- Import data fetching functions directly from `@/data`55- Define appropriate query keys for proper caching56- Structure the hook to handle loading, success, and error states57- Use TypeScript's `UseQueryOptions` or `Omit<UseQueryOptions, 'queryKey' | 'queryFn'>` for args type58- Spread additional args to allow overriding default options5960### Query Key Structure61- Use descriptive and hierarchical query keys62- Follow REST-like patterns: `['/[entity]', ...params]`63- Include relevant parameters in query keys for proper cache invalidation64- Examples:65 - Single entity: `['/[entity]', entityId]`66 - Multiple entities: `['/[entity]s']`67 - Search: `['/[entity]s', '/search', searchParams]`6869## CRUD Query Examples7071### 1. Single Entity Query (Read)72```typescript73// use-[entity]-query.ts74import { useQuery } from '@tanstack/react-query';75import { get[Entity]sBy[Entity]Id, type Get[Entity]sBy[Entity]IdData } from '@/data';7677export type Use[Entity]QueryArgs = Get[Entity]sBy[Entity]IdData;7879export function use[Entity]Query(args: Use[Entity]QueryArgs) {80 return useQuery({81 queryKey: ['/[entity]s', args.[entity]Id],82 queryFn: () => get[Entity]sBy[Entity]Id(args),83 });84}85```8687### 2. Search Query with Regular Pagination (Read Multiple)88```typescript89// use-search-[entity]s-query.ts90import { useQuery, type UseQueryOptions } from '@tanstack/react-query';91import { type ApiError, search[Entity]s, type Search[Entity]sData, type Search[Entity]sResponse } from '@/data';9293export type UseSearch[Entity]sQueryArgs = Omit<94 UseQueryOptions<Search[Entity]sResponse, ApiError>,95 'queryKey' | 'queryFn'96> & {97 payload: Search[Entity]sData;98};99100export function useSearch[Entity]sQuery({ payload, ...args }: UseSearch[Entity]sQueryArgs) {101 return useQuery({102 ...args,103 queryKey: ['/[entity]s', '/search', payload],104 queryFn: () => search[Entity]s(payload),105 });106}107```108109### 3. Search Query with Infinite Scroll (Read Multiple)110```typescript111// use-search-[entity]s-infinite-query.ts112import { useInfiniteQuery } from '@tanstack/react-query';113import { search[Entity]s, type Search[Entity]sData } from '@/data';114115export type UseSearch[Entity]sInfiniteQueryArgs = Search[Entity]sData;116117export function useSearch[Entity]sInfiniteQuery(args?: UseSearch[Entity]sInfiniteQueryArgs) {118 return useInfiniteQuery({119 queryKey: ['/[entity]s', '/search', args],120 queryFn: ({ pageParam }) => search[Entity]s({ ...args, page: pageParam }),121 initialPageParam: 1,122 getNextPageParam: lastPage => lastPage.next_page,123 getPreviousPageParam: firstPage => firstPage.previous_page,124 });125}126```127128### Complete CRUD Query Folder Structure Example129```130src/hooks/query/[entity]/131├── use-[entity]-query.ts # Read single entity132├── use-search-[entity]s-query.ts # Search with regular pagination133└── use-search-[entity]s-infinite-query.ts # Search with infinite scroll134```135136## Best Practices137138### Performance Considerations139- Implement appropriate staleTime and cacheTime based on data volatility140- Use suspense mode when applicable for concurrent rendering141- Consider implementing placeholderData or initialData for better UX142143### Error Handling144- Implement appropriate error handling strategies145- Consider using onError callbacks for specific error handling logic146- Document possible error scenarios147148### Dependent Queries149- Use the enabled option to control when a query should run150- Chain queries using the data from one query as input for another151152### Prefetching153- Implement prefetching strategies for predictable user interactions154- Use queryClient.prefetchQuery for anticipated data needs155156### Infinite Queries157- Use useInfiniteQuery for pagination or infinite scrolling scenarios158- Structure the response data to include necessary pagination metadata
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| constROD/template-react-vite.cursor/rules/data-access-via-api.mdc · 15 | Cursor rules | teststylearchtypes+1 | 74/100 | 14 days ago | |
| constROD/template-react-vite.cursor/rules/design-system.mdc · 15 | Cursor rules | lint-formatstylearchui | 58/100 | 14 days ago | |
| constROD/template-react-vite.cursor/rules/mutation-hooks.mdc · 15 | Cursor rules | stylearchtypes | 70/100 | 14 days ago | |
| constROD/template-react-vite.cursor/rules/project-structure.mdc · 15 | Cursor rules | stylearchdependencies | 78/100 | 14 days ago | |
| constROD/template-react-vite.cursor/rules/service-layer.mdc · 15 | Cursor rules | stylearchtypes | 66/100 | 14 days ago | |
| constROD/template-react-vite.cursor/rules/styling.mdc · 15 | Cursor rules | archui | 58/100 | 14 days ago | |
| constROD/template-react-vite.cursor/rules/zustand-store.mdc · 15 | Cursor rules | teststylearchtypes+1 | 74/100 | 14 days ago | |
| constROD/template-react-viteAGENTS.md · 15 | AGENTS.md | testlint-formatstylearch+3 | 90/100 | 14 days ago | |
| constROD/template-react-viteCLAUDE.md · 15 | CLAUDE.md | testlint-formatstylearch+3 | 90/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| bybren-llc/safe-agentic-workflow.cursor/rules/10-backend-python.mdc · 399 | Cursor rules | testlint-formatstylegit+4 | 97/100 | today |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/constrod-template-react-vite-cursor-rules-query-hooks)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.