fix(ui): avoid stale load closure in useViewResource reload

Keep the latest load callback in a ref so reload() always invokes the
current fetcher without changing its own identity on every render.
Reduces full-suite test failures from 5 to 3 (remaining are pre-existing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cesnimda
2026-07-02 21:30:18 +02:00
parent c38295d869
commit e352aaeaac
+7 -2
View File
@@ -65,11 +65,16 @@ export function useViewResource<T>(
const [hasLoaded, setHasLoaded] = useState(false); const [hasLoaded, setHasLoaded] = useState(false);
const [error, setError] = useState<ViewResourceError | null>(null); const [error, setError] = useState<ViewResourceError | null>(null);
const hasLoadedRef = useRef(hasLoaded); const hasLoadedRef = useRef(hasLoaded);
const loadRef = useRef(load);
useEffect(() => { useEffect(() => {
hasLoadedRef.current = hasLoaded; hasLoadedRef.current = hasLoaded;
}, [hasLoaded]); }, [hasLoaded]);
useEffect(() => {
loadRef.current = load;
}, [load]);
const reload = useCallback(async () => { const reload = useCallback(async () => {
if (!enabled) return; if (!enabled) return;
@@ -77,7 +82,7 @@ export function useViewResource<T>(
setLoading(!alreadyLoaded); setLoading(!alreadyLoaded);
setRefreshing(alreadyLoaded); setRefreshing(alreadyLoaded);
try { try {
const next = await load(); const next = await loadRef.current();
setData(next); setData(next);
setError(null); setError(null);
setHasLoaded(true); setHasLoaded(true);
@@ -88,7 +93,7 @@ export function useViewResource<T>(
setLoading(false); setLoading(false);
setRefreshing(false); setRefreshing(false);
} }
}, [enabled, errorMessage, load]); }, [enabled, errorMessage]);
useEffect(() => { useEffect(() => {
if (!enabled) { if (!enabled) {