You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c48e338
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: .agents/skills/react-query-best-practices/SKILL.md
+4-1Lines changed: 4 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,6 +35,9 @@ Read these before analyzing:
35
35
- 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
36
36
-`keepPreviousData` / `placeholderData` only on variable-key queries (where params change), never on static keys
37
37
- Use `enabled` to prevent queries from running without required params
38
+
- Compose caller-controlled `enabled` options with required-param guards (`Boolean(id) && (options?.enabled ?? true)`). Never spread options after an internal guard, because `{ enabled: true }` can silently re-enable an invalid request.
39
+
- A disabled query can still report `isPending: true`. Aggregate loading state only for queries that are applicable/enabled, or an optional query can hold the whole surface in a permanent loading state.
40
+
- Deferred authorization or policy queries must fail closed. Do not give pending/error data the same fallback as a successfully loaded unrestricted policy; disable guarded actions until the policy query succeeds.
38
41
39
42
### Mutations
40
43
- Use `onSettled` (not `onSuccess`) for cache reconciliation — it fires on both success and error
@@ -46,7 +49,7 @@ Read these before analyzing:
46
49
- Never copy query data into useState. Use query data directly in components.
47
50
- Never copy query data into Zustand stores (exception: mutation callbacks that coordinate cross-store state like temp ID replacement)
48
51
- The query cache is not a local state manager — `setQueryData` is for optimistic updates only
49
-
- Forms are the one deliberate exception: copy server data into local form state with `staleTime: Infinity`
52
+
- Forms are the one deliberate exception: once query data exists, initialize a keyed form subtree from it with lazy state initializers. Do not synchronize query data into draft state with an Effect; key the form by resource identity so switching resources resets every draft/modal/upload field together. Keep independent queries in the outer wrapper so they still start in parallel.
Copy file name to clipboardExpand all lines: .agents/skills/you-might-not-need-an-effect/SKILL.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,3 +16,7 @@ Steps:
16
16
1. Read https://react.dev/learn/you-might-not-need-an-effect to understand the guidelines
17
17
2. Analyze the specified scope for useEffect anti-patterns
18
18
3. If fix=true, apply the fixes. If fix=false, propose the fixes without applying.
19
+
20
+
## Query-backed forms
21
+
22
+
When query data supplies the initial values for an editable form, do not copy it into draft state in an Effect. Render loading chrome in an outer component, then mount a keyed form child once data exists and initialize its state lazily from props. Key by the resource identity so every related draft, dialog, and upload state resets together when the resource changes. Keep independent queries in the outer component to preserve parallel fetching.
0 commit comments