fix(P4A): guard ImageAnnotator load callbacks with cancelled flag (React strict double-mount)

This commit is contained in:
byGalax
2026-05-17 01:03:37 +02:00
parent 1e139fb86e
commit 58efc66ca7
+14 -1
View File
@@ -51,18 +51,31 @@ export function ImageAnnotator({ file, onCancel, onSave }: Props) {
useEffect(() => { onCancelRef.current = onCancel; }, [onCancel]);
useEffect(() => {
// React 18 strict mode in dev double-mounts effects to test idempotency.
// The first run creates a blob URL, sets img.src, returns a cleanup
// that revokes — and the cleanup fires BEFORE the (still-in-flight)
// image fetch completes. The browser then emits ERR_FILE_NOT_FOUND for
// the revoked URL → img.onerror → modal closes instantly. The
// `cancelled` flag guards every callback so a torn-down run can't
// close the modal that the second mount just opened.
let cancelled = false;
const url = URL.createObjectURL(file);
const img = new Image();
img.onload = () => {
if (cancelled) return;
imageRef.current = img;
setImageLoaded(true);
};
img.onerror = () => {
if (cancelled) return;
console.error('ImageAnnotator: failed to decode source image');
onCancelRef.current();
};
img.src = url;
return () => URL.revokeObjectURL(url);
return () => {
cancelled = true;
URL.revokeObjectURL(url);
};
}, [file]);
useEffect(() => {