Skip to content

Commit 1b24208

Browse files
committed
fix(input-format): field not editable race condition
1 parent feca5fa commit 1b24208

1 file changed

Lines changed: 17 additions & 10 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,17 @@ export function FieldFormat({
127127
disabled,
128128
})
129129

130+
/**
131+
* Stable fallback field used while the store value is still empty (e.g. a
132+
* newly added block). Caching it in a ref keeps the field id constant across
133+
* renders, so the inputs don't remount on each keystroke and edits commit to
134+
* the same id instead of a freshly generated one.
135+
*/
136+
const fallbackFieldRef = useRef<Field | null>(null)
137+
const fallbackField = (fallbackFieldRef.current ??= createDefaultField())
138+
130139
const value = isPreview ? previewValue : storeValue
131-
const fields: Field[] = Array.isArray(value) && value.length > 0 ? value : [createDefaultField()]
140+
const fields: Field[] = Array.isArray(value) && value.length > 0 ? value : [fallbackField]
132141
const isReadOnly = isPreview || disabled
133142

134143
const renderFieldLabel = (label: string) => <Label>{label}</Label>
@@ -155,8 +164,12 @@ export function FieldFormat({
155164
setStoreValue(fields.filter((field) => field.id !== id))
156165
}
157166

158-
const storeValueRef = useRef(storeValue)
159-
storeValueRef.current = storeValue
167+
/**
168+
* Mirrors the rendered fields (store value or stable fallback) so updateField
169+
* always commits against the same ids the UI is currently showing.
170+
*/
171+
const fieldsRef = useRef(fields)
172+
fieldsRef.current = fields
160173

161174
const isReadOnlyRef = useRef(isReadOnly)
162175
isReadOnlyRef.current = isReadOnly
@@ -173,14 +186,8 @@ export function FieldFormat({
173186
? validateFieldName(fieldValue)
174187
: fieldValue
175188

176-
const currentStoreValue = storeValueRef.current
177-
const currentFields: Field[] =
178-
Array.isArray(currentStoreValue) && currentStoreValue.length > 0
179-
? currentStoreValue
180-
: [createDefaultField()]
181-
182189
setStoreValueRef.current(
183-
currentFields.map((f) => (f.id === id ? { ...f, [fieldKey]: updatedValue } : f))
190+
fieldsRef.current.map((f) => (f.id === id ? { ...f, [fieldKey]: updatedValue } : f))
184191
)
185192
},
186193
[]

0 commit comments

Comments
 (0)