Ver Fonte

RHL-022 feat(hooks): add useExplorerQuery data-fetching hook with retry mechanism

Code_Uwe há 1 mês atrás
pai
commit
824c9b3c32
1 ficheiros alterados com 70 adições e 0 exclusões
  1. 70 0
      lib/frontend/hooks/useExplorerQuery.js

+ 70 - 0
lib/frontend/hooks/useExplorerQuery.js

@@ -0,0 +1,70 @@
+import React from "react";
+
+/**
+ * useExplorerQuery
+ *
+ * A tiny, predictable data-fetching hook for the Explorer UI.
+ *
+ * Design goals:
+ * - Keep logic centralized and consistent across all Explorer levels.
+ * - Provide stable states: loading / success / error.
+ * - Provide a retry mechanism without leaking implementation details to the UI.
+ *
+ * Non-goals:
+ * - This hook does NOT perform routing/redirects.
+ *   Routing decisions remain in the UI components for clarity.
+ *
+ * @template T
+ * @param {() => Promise<T>} loadFn - async loader (e.g. apiClient.getYears)
+ * @param {any[]} deps - dependencies that define the query identity (e.g. [branch, year])
+ * @returns {{
+ *   status: "loading"|"success"|"error",
+ *   data: T|null,
+ *   error: unknown|null,
+ *   retry: () => void
+ * }}
+ */
+export function useExplorerQuery(loadFn, deps) {
+	const [status, setStatus] = React.useState("loading");
+	const [data, setData] = React.useState(null);
+	const [error, setError] = React.useState(null);
+
+	// Incrementing this tick triggers a refetch without changing deps.
+	const [retryTick, setRetryTick] = React.useState(0);
+
+	const retry = React.useCallback(() => {
+		setRetryTick((n) => n + 1);
+	}, []);
+
+	React.useEffect(() => {
+		let cancelled = false;
+
+		async function run() {
+			setStatus("loading");
+			setError(null);
+
+			try {
+				const result = await loadFn();
+				if (cancelled) return;
+
+				setData(result);
+				setStatus("success");
+			} catch (err) {
+				if (cancelled) return;
+
+				setData(null);
+				setError(err);
+				setStatus("error");
+			}
+		}
+
+		run();
+
+		return () => {
+			cancelled = true;
+		};
+		// eslint-disable-next-line react-hooks/exhaustive-deps
+	}, [...deps, retryTick]);
+
+	return { status, data, error, retry };
+}