CtrlK
BlogDocsLog inGet started
Tessl Logo

react-query-best-practices

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

69

Quality

85%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

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.
Repository
simstudioai/sim
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.