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
**Note:** The lazy initializer captures the initial prop value. If `store` is initially undefined but becomes defined later, `storeInstance` will remain the created store. This matches the original ref behavior and is typically intentional.
Storing refs in state and comparing `.current` values during render is also a violation of this rule. Instead, use a string or enum identifier to track which element is selected.
> Reason: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)
292
+
293
+
The `store?.useState()` pattern conditionally calls a hook - when `store` is `undefined`, the hook isn't called; when defined, it is. This violates the Rules of Hooks which require hooks to be called unconditionally in the same order on every render.
The `store.useState()` pattern is from older versions of AriaKit. Since [version 0.4.9](https://ariakit.org/changelog#new-usestorestate-hook), AriaKit provides [`useStoreState`](https://ariakit.org/reference/use-store-state) which accepts stores that are null or undefined, returning undefined in those cases. The same principle applies to any conditional hook call - use an API that handles the conditional case internally.
310
+
311
+
### Function declaration order
312
+
313
+
> Reason: Cannot access variable before it is declared
314
+
>
315
+
> handleFormInputEnter is accessed before it is declared, which prevents the earlier access from updating when this value changes over time
316
+
317
+
or
318
+
319
+
> Reason: [PruneHoistedContexts] Rewrite hoisted function references
320
+
321
+
The compiler analyzes function dependencies statically. Functions must be declared before they're referenced by other functions.
322
+
323
+
**Before:**
324
+
325
+
```typescript
326
+
function handleFormInputEnter(event:KeyboardEvent) {
327
+
onChange?.(getCurrentEditorValue())
328
+
handleFormSubmit(event) // Error: accessed before declaration
329
+
}
330
+
331
+
function handleFormSubmit(event:KeyboardEvent|React.MouseEvent) {
332
+
// ...
333
+
}
334
+
```
335
+
336
+
**After:**
337
+
338
+
```typescript
339
+
function handleFormSubmit(event:KeyboardEvent|React.MouseEvent) {
340
+
// ...
341
+
}
342
+
343
+
function handleFormInputEnter(event:KeyboardEvent) {
344
+
onChange?.(getCurrentEditorValue())
345
+
handleFormSubmit(event) // Now valid
346
+
}
347
+
```
348
+
224
349
## Verifying fixes (for LLMs)
225
350
226
351
When fixing violations programmatically, use one of these methods to verify the fix was successful:
227
352
228
353
**1. CLI Tool (recommended)**
229
354
230
-
Run the tracker to check if a file has violations:
355
+
Run the tracker with `--overwrite`to regenerate the records file, then check if the entry remains or if its error count has reduced:
A successful check produces no output. If violations remain, the tool reports the error count.
361
+
Compare `.react-compiler.rec.json` before and after: if the file's entry is removed or its error count decreased, the fix was successful.
362
+
363
+
**Note:** This runs against the entire codebase, not just the modified file. The workaround is needed because `--check-files` doesn't report resolved errors ([react-compiler-tracker#35](https://github.com/Doist/react-compiler-tracker/issues/35)).
0 commit comments