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
Copy file name to clipboardExpand all lines: .claude/commands/you-might-not-need-a-callback.md
+25-8Lines changed: 25 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,17 +16,34 @@ User arguments: $ARGUMENTS
16
16
Read before analyzing:
17
17
1.https://react.dev/reference/react/useCallback — official docs on when useCallback is actually needed
18
18
19
+
## The one rule that matters
20
+
21
+
`useCallback` is only useful when **something observes the reference**. Ask: does anything care if this function gets a new identity on re-render?
22
+
23
+
Observers that care about reference stability:
24
+
- A `useEffect` that lists the function in its deps array
25
+
- A `useMemo` that lists the function in its deps array
26
+
- Another `useCallback` that lists the function in its deps array
27
+
- A child component wrapped in `React.memo` that receives the function as a prop
28
+
29
+
If none of those apply — if the function is only called inline, or passed to a non-memoized child, or assigned to a native element event — the reference is unobserved and `useCallback` adds overhead with zero benefit.
30
+
19
31
## Anti-patterns to detect
20
32
21
-
1.**useCallback on functions not passed as props or deps**: No benefit if only called within the same component.
22
-
2.**useCallback with deps that change every render**: Memoization is wasted.
23
-
3.**useCallback on handlers passed to native elements**: `<button onClick={fn}>` doesn't benefit from stable references.
24
-
4.**useCallback wrapping functions that return new objects/arrays**: Memoization at the wrong level.
25
-
5.**useCallback with empty deps when deps are needed**: Stale closures.
26
-
6.**Pairing useCallback + React.memo unnecessarily**: Only optimize when you've measured a problem.
27
-
7.**useCallback in hooks that don't need stable references**: Not every hook return needs memoization.
33
+
1.**No observer tracks the reference**: The function is only called inline in the same component, or passed to a non-memoized child, or used as a native element handler (`<button onClick={fn}>`). Nothing re-runs or bails out based on reference identity. Remove `useCallback`.
34
+
2.**useCallback with deps that change every render**: If a dep is a plain object/array created inline, or state that changes on every interaction, memoization buys nothing — the function gets a new identity anyway.
35
+
3.**useCallback on handlers passed only to native elements**: `<button onClick={fn}>` — React never does reference equality on native element props. No benefit.
36
+
4.**useCallback wrapping functions that return new objects/arrays**: Stable function identity, unstable return value — memoization is at the wrong level. Use `useMemo` on the return value instead, or restructure.
37
+
5.**useCallback with empty deps when deps are needed**: Stale closure — reads initial values forever. This is a correctness bug, not just a performance issue.
38
+
6.**Pairing useCallback + React.memo on trivially cheap renders**: If the child renders in < 1ms and re-renders rarely, the memo infrastructure costs more than it saves.
39
+
40
+
## Patterns that ARE correct — do not flag
28
41
29
-
Note: This codebase uses a ref pattern for stable callbacks (`useRef` + empty deps). That pattern is correct — don't flag it.
42
+
-`useCallback` whose result is in a `useEffect` dep array — prevents the effect from re-running on every render
43
+
-`useCallback` whose result is in a `useMemo` dep array — prevents the memo from recomputing on every render
44
+
-`useCallback` whose result is a dep of another `useCallback` — stabilises a callback chain
45
+
-`useCallback` passed to a `React.memo`-wrapped child — the whole point of the pattern
46
+
- This codebase's ref pattern: `useRef` + callback with empty deps that reads the ref inside — correct, do not flag
selected_outputs=["agent1.content"] # Use blockName.attribute format
621
621
)
@@ -758,4 +758,15 @@ Configure the client using environment variables:
758
758
759
759
## License
760
760
761
-
Apache-2.0
761
+
Apache-2.0
762
+
763
+
import { FAQ } from'@/components/ui/faq'
764
+
765
+
<FAQitems={[
766
+
{ question: "Do I need to deploy a workflow before I can execute it via the SDK?", answer: "Yes. Workflows must be deployed before they can be executed through the SDK. You can use the validate_workflow() method to check whether a workflow is deployed and ready. If it returns False, deploy the workflow from the Sim UI first and create or select an API key during deployment." },
767
+
{ question: "What is the difference between sync and async execution?", answer: "Sync execution (the default) blocks until the workflow completes and returns the full result. Async execution (async_execution=True) returns immediately with a task ID that you can poll using get_job_status(). Use async mode for long-running workflows to avoid request timeouts. Async job statuses include queued, processing, completed, failed, and cancelled." },
768
+
{ question: "How does the SDK handle rate limiting?", answer: "The SDK provides built-in rate limiting support through the execute_with_retry() method. It uses exponential backoff (1s, 2s, 4s, 8s...) with 25% jitter to avoid thundering herd problems. If the API returns a retry-after header, that value is used instead. You can configure max_retries, initial_delay, max_delay, and backoff_multiplier. Use get_rate_limit_info() to check your current rate limit status." },
769
+
{ question: "Can I use the Python SDK as a context manager?", answer: "Yes. The SimStudioClient supports Python's context manager protocol. Use it with the 'with' statement to automatically close the underlying HTTP session when you are done, which is especially useful for scripts that create and discard client instances." },
770
+
{ question: "How do I handle different types of errors from the SDK?", answer: "The SDK raises SimStudioError with a code property for API-specific errors. Common error codes are UNAUTHORIZED (invalid API key), TIMEOUT (request timed out), RATE_LIMIT_EXCEEDED (too many requests), USAGE_LIMIT_EXCEEDED (billing limit reached), and EXECUTION_ERROR (workflow failed). Use the error code to implement targeted error handling and recovery logic." },
771
+
{ question: "How do I monitor my API usage and remaining quota?", answer: "Use the get_usage_limits() method to check your current usage. It returns sync and async rate limit details (limit, remaining, reset time, whether you are currently limited), plus your current period cost, usage limit, and plan tier. This lets you monitor consumption and alert before hitting limits." },
0 commit comments