fix: stop manifest editor base image selection loop

The ManifestEditor had a feedback loop:
1. State change → buildManifest changes → onChange notifies parent
2. Parent updates manifestData → new manifest prop
3. Loading effect sets all state from manifest (arrays get new refs even if same content)
4. New array refs → buildManifest changes → onChange fires again → loop

Fix: track the last-sent manifest via a ref and only call onChange when the
serialized built manifest actually differs. This breaks the cycle because after
the loading effect syncs state, the rebuilt manifest is identical in content
so we skip the parent notification.
This commit is contained in:
Alex Blank
2026-05-28 21:44:49 +02:00
parent 3aa56dcfc3
commit 0a0af4e02a
3 changed files with 112 additions and 73 deletions
+13 -4
View File
@@ -1,4 +1,4 @@
import { useState, useEffect, useCallback } from "react";
import { useState, useEffect, useCallback, useRef } from "react";
import { Icon } from "./icon";
import { extractErrorMessage } from "../utils/errors";
import {
@@ -170,11 +170,20 @@ export const ManifestEditor = ({
baseDefinitionId,
]);
// Notify parent of changes
// Notify parent of changes — only when built manifest actually differs
// from what we last sent, to avoid feedback loops with the manifest prop.
const lastSentRef = useRef<string>("");
const onChangeRef = useRef(onChange);
onChangeRef.current = onChange;
useEffect(() => {
const m = buildManifest();
onChange(m);
}, [buildManifest, onChange]);
const serialized = JSON.stringify(m);
if (serialized !== lastSentRef.current) {
lastSentRef.current = serialized;
onChangeRef.current(m);
}
}, [buildManifest]);
const handlePreview = async () => {
if (!definitionId) {