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 <noreply@anthropic.com>
This commit is contained in:
Asep Haryana Saputra
2026-05-22 17:09:24 +00:00
co-authored by Claude Opus 4.7
parent 7fb8b075b8
commit 0027c0ed05
@@ -17,6 +17,7 @@ export function ImageClassificationForm({
latestResult,
}: ImageClassificationFormProps) {
const fileInputRef = useRef<HTMLInputElement>(null);
const previewUrlRef = useRef<string | null>(null);
const [file, setFile] = useState<File | null>(null);
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
const [error, setError] = useState<string | null>(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<HTMLFormElement>) {
@@ -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);