fix(travel): useTravelData AbortController 및 에러 핸들링 보완
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,7 @@ const useTravelData = () => {
|
|||||||
const currentAlbumRef = useRef(null); // { regionId, albumName }
|
const currentAlbumRef = useRef(null); // { regionId, albumName }
|
||||||
const cacheRef = useRef(new Map()); // photo data cache key: `${regionId}::${albumName}`
|
const cacheRef = useRef(new Map()); // photo data cache key: `${regionId}::${albumName}`
|
||||||
const albumCacheRef = useRef(new Map()); // album metadata cache key: regionId
|
const albumCacheRef = useRef(new Map()); // album metadata cache key: regionId
|
||||||
|
const loadAbortRef = useRef(null); // AbortController for loadAlbumPhotos
|
||||||
|
|
||||||
/* ── Load GeoJSON regions once ──────────── */
|
/* ── Load GeoJSON regions once ──────────── */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -195,7 +196,10 @@ const useTravelData = () => {
|
|||||||
setHasNext(false);
|
setHasNext(false);
|
||||||
pageRef.current = 1;
|
pageRef.current = 1;
|
||||||
|
|
||||||
|
// Abort any in-flight loadAlbumPhotos request
|
||||||
|
if (loadAbortRef.current) loadAbortRef.current.abort();
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
loadAbortRef.current = controller;
|
||||||
try {
|
try {
|
||||||
let url = `/api/travel/photos?region=${encodeURIComponent(regionId)}&page=1&size=${PAGE_SIZE}`;
|
let url = `/api/travel/photos?region=${encodeURIComponent(regionId)}&page=1&size=${PAGE_SIZE}`;
|
||||||
if (albumName) url += `&album=${encodeURIComponent(albumName)}`;
|
if (albumName) url += `&album=${encodeURIComponent(albumName)}`;
|
||||||
@@ -241,11 +245,12 @@ const useTravelData = () => {
|
|||||||
setLoadingMore(true);
|
setLoadingMore(true);
|
||||||
setError('');
|
setError('');
|
||||||
|
|
||||||
|
const moreController = new AbortController();
|
||||||
try {
|
try {
|
||||||
let url = `/api/travel/photos?region=${encodeURIComponent(activeRegion)}&page=${pageRef.current}&size=${PAGE_SIZE}`;
|
let url = `/api/travel/photos?region=${encodeURIComponent(activeRegion)}&page=${pageRef.current}&size=${PAGE_SIZE}`;
|
||||||
if (activeAlbum) url += `&album=${encodeURIComponent(activeAlbum)}`;
|
if (activeAlbum) url += `&album=${encodeURIComponent(activeAlbum)}`;
|
||||||
|
|
||||||
const res = await fetch(url);
|
const res = await fetch(url, { signal: moreController.signal });
|
||||||
if (!res.ok) throw new Error(`사진 로딩 실패 (${res.status})`);
|
if (!res.ok) throw new Error(`사진 로딩 실패 (${res.status})`);
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
const { normalized, hasNext: hn, summary } = parsePhotoResponse(json);
|
const { normalized, hasNext: hn, summary } = parsePhotoResponse(json);
|
||||||
@@ -289,7 +294,9 @@ const useTravelData = () => {
|
|||||||
let url = `/api/travel/photos?region=${encodeURIComponent(activeRegion)}&page=1&size=${PAGE_SIZE}`;
|
let url = `/api/travel/photos?region=${encodeURIComponent(activeRegion)}&page=1&size=${PAGE_SIZE}`;
|
||||||
if (activeAlbum) url += `&album=${encodeURIComponent(activeAlbum)}`;
|
if (activeAlbum) url += `&album=${encodeURIComponent(activeAlbum)}`;
|
||||||
|
|
||||||
const res = await fetch(url);
|
const reloadController = new AbortController();
|
||||||
|
try {
|
||||||
|
const res = await fetch(url, { signal: reloadController.signal });
|
||||||
if (!res.ok) throw new Error(`사진 로딩 실패 (${res.status})`);
|
if (!res.ok) throw new Error(`사진 로딩 실패 (${res.status})`);
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
const { normalized, hasNext: hn, summary } = parsePhotoResponse(json);
|
const { normalized, hasNext: hn, summary } = parsePhotoResponse(json);
|
||||||
@@ -309,6 +316,10 @@ const useTravelData = () => {
|
|||||||
summary,
|
summary,
|
||||||
});
|
});
|
||||||
if (summary) setPhotoSummary(summary);
|
if (summary) setPhotoSummary(summary);
|
||||||
|
} catch (err) {
|
||||||
|
if (err?.name === 'AbortError') return;
|
||||||
|
setError(err?.message ?? String(err));
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
/* ── getFilteredAlbums — filter by region ─ */
|
/* ── getFilteredAlbums — filter by region ─ */
|
||||||
|
|||||||
Reference in New Issue
Block a user