Repository navigation
chore(lint): batch 4 of #12146 — shared/components react-hooks violations resolved - #12159
Merged
diegosouzapw merged 3 commits intoAug 31, 2026
Merged
Conversation
…lations in shared/components Real refactors (no suppressions, no eslint-disable) for the 21 react-hooks/* violations across the 11 src/shared/components files of this batch: - set-state-in-effect (prop/state mirror or modal open/close reset): replaced with guarded render-time adjustments (react.dev "You Might Not Need an Effect" prev-tracking pattern) — KiroAuthModal, ModelSelectModal, ProxyConfigModal, OAuthModal (provider-change, close and open resets; ref invalidation split into ref-only effects), RequestLoggerDetail.sections (liveDetail mirror), ComboCompressionModeSelect (initialCompressionMode mirror). - set-state-in-effect (fetch+set effects calling component-scope functions): moved the async loader inside the effect (ModelSelectModal fetchCombos/fetchProviderNodes/fetchCustomModels, PricingModal loadPricing, useProviderDailyUsage fetchRows — now with a cancelled guard) or wrapped the call in an effect-local async runner (ReasoningRoutingRules load, UsageStats fetchStats, OAuthModal startOAuthFlow) with every setState on the async path. - OAuthModal device-code countdown: deviceCodeSecondsRemaining state deleted and derived from deviceCodeExpiresAt plus a `now` tick state updated by the interval (re-anchored when polling starts). - Sidebar localStorage hydration: reads moved into useSyncExternalStore snapshots (server snapshot null) applied via render-time adjustment; skipInitialActiveExpansion ref converted to state; the active-section expansion effect became a render-time adjustment keyed on the old effect deps; persistence consolidated into one saveToStorage effect (removes the saves that ran inside setState updaters and drops a pre-existing eslint-disable for exhaustive-deps). - immutability (use-before-declare): PricingModal loadPricing inlined into its effect; ProxyConfigModal resetFields hoisted above the load effect as a dependency-free useCallback. - exhaustive-deps (ProxyConfigModal): effect now depends on the stable resetFields and on hoisted translated strings (socks5HiddenError, levelGlobalLabel) instead of the `t` identity. - preserve-manual-memoization (UsageStats sortedAccounts): optional chains destructured into locals so the memo deps match the usage. config/quality/eslint-suppressions.json: removed every react-hooks/* entry for the 11 files (other-rule entries preserved). Validation: eslint gate (--suppressions-location, --max-warnings 0) green on all 11 files; typecheck:core clean; node unit sweep 373/373; vitest sweep 547/550 with the 3 fails being 5s-timeout flakes under parallel load (all pass isolated 8/8, one in an untouched file). Refs #12146
…6-batch4-shared-components
The test (merged with the DuckDuckGo cooldown fix) covers accountFallback.ts and auth.ts but was not listed, so check:mutation-test-coverage --strict reds any PR whose merge ref includes it. Base also merged in.
xiaoyaner0201
added a commit
to xiaoyaner0201/OmniRoute
that referenced
this pull request
Aug 31, 2026
…51 @ 718accb Upstream advanced from 7f49b34 to 718accb while R4 was running (two chore commits: stryker test registration diegosouzapw#12170 and shared/components react-hooks lint batch diegosouzapw#12159). Neither touches this change's two paths, and the ESLint suppressions entry for src/app/api/v1/models/catalog.ts is unchanged at no-unused-vars: 10. Ordinary additive two-parent merge so the candidate is bound to the exact current target SHA.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…hooks violations resolved (diegosouzapw#12159) * chore(lint): batch 4 of diegosouzapw#12146 — resolve the react-hooks compiler violations in shared/components Real refactors (no suppressions, no eslint-disable) for the 21 react-hooks/* violations across the 11 src/shared/components files of this batch: - set-state-in-effect (prop/state mirror or modal open/close reset): replaced with guarded render-time adjustments (react.dev "You Might Not Need an Effect" prev-tracking pattern) — KiroAuthModal, ModelSelectModal, ProxyConfigModal, OAuthModal (provider-change, close and open resets; ref invalidation split into ref-only effects), RequestLoggerDetail.sections (liveDetail mirror), ComboCompressionModeSelect (initialCompressionMode mirror). - set-state-in-effect (fetch+set effects calling component-scope functions): moved the async loader inside the effect (ModelSelectModal fetchCombos/fetchProviderNodes/fetchCustomModels, PricingModal loadPricing, useProviderDailyUsage fetchRows — now with a cancelled guard) or wrapped the call in an effect-local async runner (ReasoningRoutingRules load, UsageStats fetchStats, OAuthModal startOAuthFlow) with every setState on the async path. - OAuthModal device-code countdown: deviceCodeSecondsRemaining state deleted and derived from deviceCodeExpiresAt plus a `now` tick state updated by the interval (re-anchored when polling starts). - Sidebar localStorage hydration: reads moved into useSyncExternalStore snapshots (server snapshot null) applied via render-time adjustment; skipInitialActiveExpansion ref converted to state; the active-section expansion effect became a render-time adjustment keyed on the old effect deps; persistence consolidated into one saveToStorage effect (removes the saves that ran inside setState updaters and drops a pre-existing eslint-disable for exhaustive-deps). - immutability (use-before-declare): PricingModal loadPricing inlined into its effect; ProxyConfigModal resetFields hoisted above the load effect as a dependency-free useCallback. - exhaustive-deps (ProxyConfigModal): effect now depends on the stable resetFields and on hoisted translated strings (socks5HiddenError, levelGlobalLabel) instead of the `t` identity. - preserve-manual-memoization (UsageStats sortedAccounts): optional chains destructured into locals so the memo deps match the usage. config/quality/eslint-suppressions.json: removed every react-hooks/* entry for the 11 files (other-rule entries preserved). Validation: eslint gate (--suppressions-location, --max-warnings 0) green on all 11 files; typecheck:core clean; node unit sweep 373/373; vitest sweep 547/550 with the 3 fails being 5s-timeout flakes under parallel load (all pass isolated 8/8, one in an untouched file). Refs diegosouzapw#12146 * test(mutation): register search-432-plan-limit-cooldown in tap.testFiles The test (merged with the DuckDuckGo cooldown fix) covers accountFallback.ts and auth.ts but was not listed, so check:mutation-test-coverage --strict reds any PR whose merge ref includes it. Base also merged in.
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.
Batch 4 of #12146: the 21
react-hooks/*React Compiler violations in the 11src/shared/componentsfiles are resolved with real refactors — noeslint-disable, and everyreact-hooks/*suppression entry for these files is removed fromconfig/quality/eslint-suppressions.json(entries for other rules are preserved).Violations resolved
set-state-in-effectcancelledguard where the deps can change) or an effect-local async runner, keeping every setState on the async path; (c) OAuthModal countdown → derived value fromdeviceCodeExpiresAt+ anowtick state; (d) Sidebar localStorage hydration →useSyncExternalStoresnapshots + render-time adjustment, persistence consolidated into a singlesaveToStorageeffectimmutability(use-before-declare)PricingModal.loadPricinginlined into its effect;ProxyConfigModal.resetFieldshoisted above the effect as a dependency-freeuseCallbackexhaustive-depsresetFieldsand on hoisted translated strings (socks5HiddenError,levelGlobalLabel) instead of thetfunction identitypreserve-manual-memoizationUsageStats.sortedAccountsoptional chains destructured into locals so the memo body matches its depsPer-file
startsInGitlabDuoSetup/if (!startsInPasteMode) startOAuthFlow()shape the #8688 source-pinning test asserts)t, e.g. the test mock, would loop the load effect)load()liveDetailmirror → render adjustmentuseSyncExternalStore+ render adjustment (ref → state); active-section expansion → render adjustment keyed on the old effect deps; one persistence effect (also removes a pre-existingeslint-disablefor exhaustive-deps)setLoading(true)dropped — loading starts true)cancelledguardinitialCompressionModemirror → render adjustmentValidation
npx eslint --suppressions-location config/quality/eslint-suppressions.json --pass-on-unpruned-suppressions --max-warnings 0 <11 files>→ exit 0npm run typecheck:core→ cleantests/unit/**/*.test.tsfiles,env -u OMNIROUTE_API_KEY): 373/373 pass (includes the OAuthModal/gitlab-duo source-pinning tests)*.test.tsxfiles,react18-json-view@0.2.10installed--no-save): 547/550; the 3 fails are 5s-timeout flakes under parallel load — all 3 files pass isolated (8/8), and one (radar-admin-sidebar) is not a touched fileRefs #12146