Repository navigation
fix(react): derive state instead of effect sync - #40
Merged
Merged
Conversation
- oxlint 1.79.0's react plugin flagged four sites: three were real, one was dead code - module-detail-panel: the routes effect reset state when `moduleId` changed, so the previous module's routes stayed committed for one frame. The result now carries the module it belongs to and the view is derived from it, so a mismatch reads as "loading" - use-trace-store: sample mode is a pure function of the traces handed in, so it is derived during render. That removes the setRows -> render -> effect cycle an unstable `liveTraces` identity used to drive (#27) and the `sameRows` guard that existed only to break it - use-trace-store: the latest-rows ref is mirrored in an effect rather than written during render - use-persistent-state: the latest-value ref was never read (the setter is already stable through its functional update), so it is gone chore(lint): drop non-actionable virtualizer rule - react/incompatible-library reports `useVirtualizer` returning functions the React Compiler cannot memoize. We do not run the compiler, so the two warnings had nothing behind them; the config records the condition to re-enable Tags: #lint #react Co-Authored-By: htjulia <htjulia1@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
oxlint1.79.0 (merged in #39) expanded itsreactplugin and surfaced 6 new warnings in existing code. Three were real, one was dead code, and two had no action behind them. Lint is back to the 3 pre-existingonly-export-componentswarnings.Not a cosmetic pass:
use-trace-store.tsis the file that produced the cold-start render loop fixed in #27, so its warnings were treated as signal.What each warning turned out to be
module-detail-panel.tsx:32set-state-in-effectuse-trace-store.ts:63set-state-in-effectuse-trace-store.ts:54refsuse-persistent-state.ts:35refstrace-table.tsx:73,module-table.tsx:76incompatible-libraryThe three fixes
module-detail-panel— routes were reset from the effect. On amoduleIdchange the effect ran after commit, so one frame rendered the new module's header next to the previous module's routes. The fetched result now carries the module it belongs to and the view derives from it, so a mismatch means "loading" with no stale frame possible. This is the pattern the brain records as "비동기 결과를 입력과 함께 저장해 파생시켜라".use-trace-store— sample mode is now derived, not synced. Sample mode is a pure function of the traces handed in, so it is computed during render viauseMemoinstead of pushed into state by an effect. That deletes thesetRows → render → effectcycle that an unstableliveTracesidentity used to drive (the "Maximum update depth exceeded" bug from #27) and thesameRowsguard that existed only to break that cycle — the defect class is now structurally impossible rather than guarded against. Sample-modeclearkeeps its exact old semantics by recording which batch was dismissed (same store-the-input idiom);loadOlderbecomes a no-op in sample mode, wherehasMorewas already always false.use-trace-store— the latest-rows ref is mirrored in an effect rather than assigned during render.loadOlderreads it from an event handler, which always runs after effects have flushed.use-persistent-state— dead ref removed. Its comment claimed the ref kept the setter identity stable, but the setter is auseCallback([])using the functional update form, and the ref was never read.The two left alone
react/incompatible-libraryfires onuseVirtualizerbecause it returns functions the React Compiler cannot memoize. This project does not run the compiler (plain@vitejs/plugin-react, nobabel-plugin-react-compiler), so the warning has no fix — only suppression — and it would fire on every future virtualized table. It is turned off in.oxlintrc.jsonwith the condition to re-enable written next to it.Verification
npm run lint— exit 0, 9 warnings → 3 (the pre-existingonly-export-componentsinsrc/components/ui/)npm run build/tsc -b— exit 0mainand the only difference is one dropped rule:.contents{display:contents}. That utility existed solely because the word "contents" appeared in a source comment that this PR removes — nothing usesclass="contents"(grepped). Not a regression.Module wk-crash+ROUTES loading…, never the prior module's routesClear(two-click confirm) empties the sample view and it stays empty, matching the previous behaviour