useHistorySubview returned a fresh object with a fresh `open` on every render. Correct, but it made "re-run when the sub-view moves" unwriteable: PlexBrowse had three effects that wanted exactly that and had to disable the dependency check to get it, and a fourth that listed `sub` honestly and therefore re-ran on EVERY parent render, saved only by a ref guard. Fixed at the source, which is where the house rule says a principle belongs: `open` and `back` are useCallbacks and the returned object is memoised. `url` is a module constant at every call site (PLEX_SUB_URL, MODE_URL) and the body otherwise touches only module functions, so there is nothing left to churn on. All three PlexBrowse dep lists are now the honest ones, and the comment that claimed `open` was "behaviourally stable" is replaced by it actually being stable. PlexBrowse's remaining four are escape hatches, and two of them are now ONE: - `infoScrollRef` is written from four places, and the compiler objects to a ref being modified outside the effect that reads it. That objection is a conservative false positive — a scroll memory needs exactly that arrangement — but four bare mutations were worth concentrating anyway. One `rememberInfoScroll` writer now holds the "stash on the way out, reset on a fresh page" rule, and answers the checker once instead of three times. - The language-commit effect cannot move into render: it resets PlexProvider's filters, and a render-phase setState may only touch the component's own state. Said so at the site. Suppressions 78 -> 75; exhaustive-deps 23 -> 20.
160 lines
3.2 KiB
JSON
160 lines
3.2 KiB
JSON
{
|
|
"src/components/BootGate.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/ChannelPage.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 2
|
|
}
|
|
},
|
|
"src/components/ChannelTags.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 2
|
|
}
|
|
},
|
|
"src/components/ConfigPanel.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/DateFilterSelect.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/DebugRecorder.dom.test.tsx": {
|
|
"react-hooks/globals": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/DebugRecorder.tsx": {
|
|
"react-hooks/purity": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/DiagnosticsSettings.tsx": {
|
|
"react-hooks/purity": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/DownloadCenter.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/Feed.tsx": {
|
|
"react-hooks/immutability": {
|
|
"count": 1
|
|
},
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/FeedFiltersProvider.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/GlassTuner.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
},
|
|
"react-hooks/use-memo": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/Home.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 2
|
|
}
|
|
},
|
|
"src/components/IssueComposer.tsx": {
|
|
"react-hooks/immutability": {
|
|
"count": 2
|
|
}
|
|
},
|
|
"src/components/MyLogViewer.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/PersonalViewsModal.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/PlayerModal.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/Playlists.tsx": {
|
|
"react-hooks/immutability": {
|
|
"count": 2
|
|
},
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/PlexInfo.tsx": {
|
|
"react-hooks/static-components": {
|
|
"count": 3
|
|
}
|
|
},
|
|
"src/components/PlexPlayer.tsx": {
|
|
"react-hooks/immutability": {
|
|
"count": 1
|
|
},
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/PlexSearchBox.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/Scheduler.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 2
|
|
}
|
|
},
|
|
"src/components/SetupWizard.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/TagFilterChips.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/WatchPage.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/Welcome.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/comfortPin.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/downloadRow.tsx": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
},
|
|
"src/components/usePlexPlaylistEdits.ts": {
|
|
"react-hooks/set-state-in-effect": {
|
|
"count": 1
|
|
}
|
|
}
|
|
}
|