From 0027c0ed056d0a11acc899cea30bfeaff9e4d3f0 Mon Sep 17 00:00:00 2001 From: Asep Haryana Saputra <90584806+MythEclipse@users.noreply.github.com> Date: Fri, 22 May 2026 17:09:24 +0000 Subject: [PATCH] fix: revoke active upload preview on unmount Track the active object URL in previewUrlRef to ensure the cleanup effect revokes the correct URL on unmount, avoiding closure over stale state. When replacing or clearing preview, revoke the ref's current URL and set it to null. On unmount, revoke previewUrlRef.current if present. Co-Authored-By: Claude Opus 4.7 --- .../components/image-classification-form.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/web/src/components/image-classification-form.tsx b/apps/web/src/components/image-classification-form.tsx index 1f73ffb..87f259f 100644 --- a/apps/web/src/components/image-classification-form.tsx +++ b/apps/web/src/components/image-classification-form.tsx @@ -17,6 +17,7 @@ export function ImageClassificationForm({ latestResult, }: ImageClassificationFormProps) { const fileInputRef = useRef(null); + const previewUrlRef = useRef(null); const [file, setFile] = useState(null); const [previewUrl, setPreviewUrl] = useState(null); const [error, setError] = useState(null); @@ -24,8 +25,9 @@ export function ImageClassificationForm({ // Revoke object URL on component unmount useEffect(() => { return () => { - if (previewUrl) { - URL.revokeObjectURL(previewUrl); + if (previewUrlRef.current) { + URL.revokeObjectURL(previewUrlRef.current); + previewUrlRef.current = null; } }; }, []); @@ -36,11 +38,14 @@ export function ImageClassificationForm({ setFile(selectedFile); // Revoke previous preview URL before replacing it - if (previewUrl) { - URL.revokeObjectURL(previewUrl); + if (previewUrlRef.current) { + URL.revokeObjectURL(previewUrlRef.current); + previewUrlRef.current = null; } - setPreviewUrl(selectedFile ? URL.createObjectURL(selectedFile) : null); + const newUrl = selectedFile ? URL.createObjectURL(selectedFile) : null; + previewUrlRef.current = newUrl; + setPreviewUrl(newUrl); } async function handleSubmit(event: FormEvent) { @@ -54,8 +59,9 @@ export function ImageClassificationForm({ await onSubmit(file); // Revoke current preview URL after successful submit before setting null - if (previewUrl) { - URL.revokeObjectURL(previewUrl); + if (previewUrlRef.current) { + URL.revokeObjectURL(previewUrlRef.current); + previewUrlRef.current = null; } setFile(null);