

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456# React Hooks Rules78## Core Principles9- Use TanStack Query (React Query) as primary data fetching solution10- Use useAsync/useAsyncFn for one-off async operations11- Follow hooks naming conventions ( use-something.ts )12- Handle loading and error states consistently13- Never build large hooks, use single responsibility1415## TanStack Query Patterns16```tsx17import { useQuery, useMutation } from '@tanstack/react-query'1819// Data fetching with proper types20export function useUserData(userId: string) {21 return useQuery({22 queryKey: ['user', userId],23 queryFn: async () => {24 const data = await fetchUser(userId)25 return data as User26 }27 })28}2930// Mutation with optimistic updates31export function useUpdateUser() {32 const queryClient = useQueryClient()3334 return useMutation({35 mutationFn: updateUser,36 onMutate: async (newUser) => {37 await queryClient.cancelQueries({ queryKey: ['user', newUser.id] })38 const previousUser = queryClient.getQueryData(['user', newUser.id])3940 queryClient.setQueryData(['user', newUser.id], newUser)41 return { previousUser }42 },43 onError: (err, newUser, context) => {44 queryClient.setQueryData(45 ['user', newUser.id],46 context?.previousUser47 )48 }49 })50}51```5253## Async Operations54```tsx55import { useAsync, useAsyncFn } from 'react-use'5657// For values that load once and remain static58export function useStaticData() {59 const state = useAsync(async () => {60 const data = await fetchStaticData()61 return data62 }, [])6364 return state65}6667// For operations that need manual triggering68export function useManualOperation() {69 const [state, execute] = useAsyncFn(async (params) => {70 const result = await someOperation(params)71 return result72 }, [])7374 return { state, execute }75}76```7778## Custom Hooks Patterns79```tsx80// Combine multiple queries81export function useUserWithPosts(userId: string) {82 const user = useQuery({83 queryKey: ['user', userId],84 queryFn: () => fetchUser(userId)85 })8687 const posts = useQuery({88 queryKey: ['posts', userId],89 queryFn: () => fetchUserPosts(userId),90 enabled: !!user.data91 })9293 return {94 user: user.data,95 posts: posts.data,96 isLoading: user.isLoading || posts.isLoading,97 error: user.error || posts.error98 }99}100```101102## Error Handling103- Always handle loading, error, and success states104- Use proper error boundaries for query errors105- Implement retry logic where appropriate106- Show user-friendly error messages107108## Performance109- Use proper query keys for caching110- Implement stale-while-revalidate patterns111- Use suspense mode when appropriate112- Handle pagination and infinite queries efficiently113```114115```
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 |
|---|---|---|---|---|---|
| L1Network/chaingraph.cursor/rules/tailwind.mdc · 5 | Cursor rules | styleuido-not | 42/100 | 14 days ago | |
| L1Network/chaingraph.cursor/rules/typescript.mdc · 5 | Cursor rules | stylearchtypesdo-not | 65/100 | 14 days ago | |
| L1Network/chaingraph.cursor/rules/web-vitals-perf.mdc · 5 | Cursor rules | performancedo-not | 32/100 | 14 days ago | |
| L1Network/chaingraph.cursor/rules/nextjs.mdc · 5 | Cursor rules | styleuiperformancedo-not | 65/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 · 45 | Cursor rules | testlint-formatstylearch+5 | 100/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 | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 14 days ago |
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/l1network-chaingraph-cursor-rules-react-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.