⁉️ Why
We have 8 modules tracked in .react-compiler.rec.json. Fixing them lets the compiler memoize those modules automatically and pushes us toward the better React patterns the compiler expects.
🗺 Overview
Each sub-issue tracks a single module from .react-compiler.rec.json. To close one:
- Find the violations. Run
npx @doist/react-compiler-tracker --check-files --show-errors <file> to list each violation's line number and reason. (--show-errors needs tracker 2.2.0+; the repo currently pins 2.1.2, so use @latest or bump the dep.)
- Fix them. Use the patterns in
docs/react-guidelines/react-compiler.md. The Error reference table maps each compiler message to its fix-pattern section.
- Confirm the count dropped.
npx @doist/react-compiler-tracker --check-files <file> reports the decrease. This command is read-only; the pre-commit hook (lint-staged.config.js, npx @doist/react-compiler-tracker --stage-record-file) is what removes the file's entry from .react-compiler.rec.json.
- Verify memoization landed. A clean tracker run alone does not prove it: the compiler can silently skip memoization with no error. Inspect the compiled output and confirm the memo slots (
const $ = _c(N) and the $[n] !== value cache guards) cover the values that should be memoized.
- Document new patterns. If a fix is not covered by the docs, add it to
shared/react-guidelines/react-compiler.md in Doist/shared-configs, which syncs back into this repo's docs/.
Once every sub-issue is closed, the only entry left in .react-compiler.rec.json should be the won't-fix module under Out of scope (use-previous).
🚧 Potential problems / unknowns
- Do not remove manual
useMemo/useCallback while a file still has violations.
- Fixing flagged violations in a component/hook may reveal additional violations that were not previously flagged.
- AriaKit store hooks are the most common cause, and the fix is the same for all of them. Seven of the 13 violations (across
menu, tabs, and tooltip) come from store.useState(...) (e.g. menuStore.useState('open'), including the optional-chained tabContextValue?.tabStore.useState('selectedId')). The fix is to migrate to useStoreState(store, key) from @ariakit/react, which Reactist already has (0.4.19). ✨ Fixing the three components together will clear more than half the list.
useId in common-helpers accesses refs during render as a render-persistent cache and is already @deprecated; the fix is likely to migrate callers to React 18's useId rather than patch it, which affects every consumer.
🔮 Out of scope / future improvements
src/hooks/use-previous/use-previous.ts: won't fix. The hook returns ref.current during render by design, where the ref was written by an effect on the previous render. That is the only way to implement "value from the previous render" in React today, and the compiler's own warning acknowledges the ref can be stale. Making it compiler-compatible would change its behavior, so we'll leave it tracked in .react-compiler.rec.json unless we migrate its use to a library.
📝 Related documents & discussions
Issue by violation type
| Violation |
Sub-issues |
Cannot access refs during render |
|
Hooks must be the same function on every render (AriaKit store.useState) |
|
Hooks must always be called in a consistent order (conditional hook) |
|
React ESLint rules were disabled |
|
Support destructuring of context variables |
|
LogicalExpression cannot be safely reordered |
|
We have 8 modules tracked in
.react-compiler.rec.json. Fixing them lets the compiler memoize those modules automatically and pushes us toward the better React patterns the compiler expects.🗺 Overview
Each sub-issue tracks a single module from
.react-compiler.rec.json. To close one:npx @doist/react-compiler-tracker --check-files --show-errors <file>to list each violation's line number and reason. (--show-errorsneeds tracker 2.2.0+; the repo currently pins 2.1.2, so use@latestor bump the dep.)docs/react-guidelines/react-compiler.md. The Error reference table maps each compiler message to its fix-pattern section.npx @doist/react-compiler-tracker --check-files <file>reports the decrease. This command is read-only; the pre-commit hook (lint-staged.config.js,npx @doist/react-compiler-tracker --stage-record-file) is what removes the file's entry from.react-compiler.rec.json.const $ = _c(N)and the$[n] !== valuecache guards) cover the values that should be memoized.shared/react-guidelines/react-compiler.mdinDoist/shared-configs, which syncs back into this repo'sdocs/.Once every sub-issue is closed, the only entry left in
.react-compiler.rec.jsonshould be the won't-fix module under Out of scope (use-previous).🚧 Potential problems / unknowns
useMemo/useCallbackwhile a file still has violations.menu,tabs, andtooltip) come fromstore.useState(...)(e.g.menuStore.useState('open'), including the optional-chainedtabContextValue?.tabStore.useState('selectedId')). The fix is to migrate touseStoreState(store, key)from@ariakit/react, which Reactist already has (0.4.19). ✨ Fixing the three components together will clear more than half the list.useIdincommon-helpersaccesses refs during render as a render-persistent cache and is already@deprecated; the fix is likely to migrate callers to React 18'suseIdrather than patch it, which affects every consumer.🔮 Out of scope / future improvements
src/hooks/use-previous/use-previous.ts: won't fix. The hook returnsref.currentduring render by design, where the ref was written by an effect on the previous render. That is the only way to implement "value from the previous render" in React today, and the compiler's own warning acknowledges the ref can be stale. Making it compiler-compatible would change its behavior, so we'll leave it tracked in.react-compiler.rec.jsonunless we migrate its use to a library.📝 Related documents & discussions
docs/react-guidelines/react-compiler.md.react-compiler.rec.jsonIssue by violation type
Cannot access refs during renderuseId, ×2)Hooks must be the same function on every render(AriaKitstore.useState)menu, ×2)tooltip)tabs, ×1)Hooks must always be called in a consistent order(conditional hook)tabs, ×3)React ESLint rules were disableduse-fork-ref)Support destructuring of context variablescheckbox-field)LogicalExpression cannot be safely reorderedkeyboard-shortcut)