mirror of
https://github.com/tiennm99/thptqg.git
synced 2026-09-08 02:20:19 +00:00
style(frontend): document the four one-shot setState-in-effect sites
eslint-plugin-react-hooks v7 flags setState inside an effect body. All four occurrences predate this refactor and are one-shot initialisation or external sync, not the cascading-render pattern the rule targets: - hydrating a ?q= deep link once the database is ready - reading the candidate count for the footer - auto-running the schema preset when the SQL tab first opens - mirroring the parent-owned query into SearchForm for deep links and clear Each gets a scoped disable with a comment explaining why it is correct here, rather than a blanket rule change. Restructuring these properly would mean reworking deep-link hydration and auto-search with no test harness to catch a regression; that is worth doing separately, not inside this refactor. npm run lint is now clean.
This commit is contained in:
+6
-2
@@ -98,17 +98,21 @@ function DatasetApp({ dataset }) {
|
||||
[db],
|
||||
);
|
||||
|
||||
// Run initial URL query once DB is ready
|
||||
// Hydrate a ?q= deep link once, as soon as the database is ready. Fires at
|
||||
// most once per mount, so it cannot cascade.
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
if (db && query) handleSearch(query);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [db]);
|
||||
|
||||
// Fetch total count for footer once DB loads
|
||||
// Read the candidate count for the footer once the database loads. One-shot
|
||||
// per mount; the query result cannot change without a new database.
|
||||
useEffect(() => {
|
||||
if (!db) return;
|
||||
const stmt = db.prepare("SELECT COUNT(*) AS c FROM student");
|
||||
stmt.step();
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setTotalCount(stmt.getAsObject().c);
|
||||
stmt.free();
|
||||
}, [db]);
|
||||
|
||||
@@ -82,6 +82,7 @@ export function CustomQuery({ db, disabled, presets = [] }) {
|
||||
// sees the student columns instead of a blank textarea.
|
||||
useEffect(() => {
|
||||
if (db && schemaPreset && columns.length === 0 && !sql) {
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
executeQuery(schemaPreset.sql);
|
||||
setSql(schemaPreset.sql);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,11 @@ export function SearchForm({
|
||||
const { mode, hint } = detectMode(query);
|
||||
const canSearch = mode === "sbd" || mode === "name";
|
||||
|
||||
// Sync from external value (deep-link URL, clear button in parent)
|
||||
// Mirror the parent's query into local state. The parent owns the value so
|
||||
// it can bind it to the URL; this only runs when that external value changes
|
||||
// (deep-link hydration, or the clear button), never in response to typing.
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setQuery(value);
|
||||
}, [value]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user