agentleFS
Ame-AlAme-Al/ame/.agents/skills/react-query-best-practices/SKILL.md

react-query-best-practices

Skill1 starsChanged 2 months agoApache-2.0View on GitHub

Audit React Query usage for best practices — key factories, staleTime, mutations, and server state ownership

We split this skill into the rules it gives an agent

12 rules. About 0 are common, 5 are distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read these before analyzing:

    line 21
  2. Very specific:

    Every file in hooks/queries/ must have a hierarchical key factory with an all root key

    line 29
  3. Very specific:

    Every queryFn must forward signal for request cancellation

    line 34
  4. Very specific:

    Every query must have an explicit staleTime (default 0 is almost never correct), assigned from a named exported constant — never an inline …

    line 35
  5. Very specific:

    Use enabled to prevent queries from running without required params

    line 37
  6. Very specific:

    Use onSettled (not onSuccess) for cache reconciliation — it fires on both success and error

    line 40
  7. Very specific:

    Use targeted invalidation (entityKeys.lists()) not broad (entityKeys.all) when possible

    line 42
  8. Very specific:

    Don't include mutation objects in useCallback deps — .mutate() is stable

    line 43
  9. Distinctive:

    Never copy query data into useState.

    line 46
  10. Distinctive:

    Never copy query data into Zustand stores (exception: mutation callbacks that coordinate cross-store state like temp ID replacement)

    line 47
  11. Distinctive:

    Read the references above to understand the guidelines

    line 53
  12. Distinctive:

    If fix=true, apply the fixes.

    line 55

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

React Query Best Practices

Arguments:

  • scope: what to analyze (default: your current changes). Examples: "diff to main", "PR #123", "src/hooks/queries/", "whole codebase"
  • fix: whether to apply fixes (default: true). Set to false to only propose changes.

User arguments: $ARGUMENTS

Context

This codebase uses React Query (TanStack Query) as the single source of truth for all server state. All query hooks live in hooks/queries/. Zustand is used only for client-only UI state. Server data must never be duplicated into useState or Zustand outside of mutation callbacks that coordinate cross-store state.

References

Read these before analyzing:

  1. https://tkdodo.eu/blog/practical-react-query — foundational defaults, custom hooks, avoiding local state copies
  2. https://tkdodo.eu/blog/effective-react-query-keys — key factory pattern, hierarchical keys, fuzzy invalidation
  3. https://tkdodo.eu/blog/react-query-as-a-state-manager — React Query IS your server state manager

Rules to enforce

Query key factories

  • Every file in hooks/queries/ must have a hierarchical key factory with an all root key
  • Keys must include intermediate plural keys (lists, details) for prefix invalidation
  • Key factories are colocated with their query hooks, not in a global keys file

Query hooks

  • Every queryFn must forward signal for request cancellation
  • Every query must have an explicit staleTime (default 0 is almost never correct), assigned from a named exported constant — never an inline numeric literal. A server-side prefetch hydrating the same query key must import and reuse that constant instead of restating the number
  • keepPreviousData / placeholderData only on variable-key queries (where params change), never on static keys
  • Use enabled to prevent queries from running without required params

Mutations

  • Use onSettled (not onSuccess) for cache reconciliation — it fires on both success and error
  • For optimistic updates: save previous data in onMutate, roll back in onError
  • Use targeted invalidation (entityKeys.lists()) not broad (entityKeys.all) when possible
  • Don't include mutation objects in useCallback deps — .mutate() is stable

Server state ownership

  • Never copy query data into useState. Use query data directly in components.
  • Never copy query data into Zustand stores (exception: mutation callbacks that coordinate cross-store state like temp ID replacement)
  • The query cache is not a local state manager — setQueryData is for optimistic updates only
  • Forms are the one deliberate exception: copy server data into local form state with staleTime: Infinity

Steps

  1. Read the references above to understand the guidelines
  2. Analyze the specified scope against the rules listed above
  3. If fix=true, apply the fixes. If fix=false, propose the fixes without applying.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.