Validation error not cleared in custom array field component using useControl
#914
Replies: 2 comments
-
I am guessing the issue you had was because of the select not have the corresponding option to reflect the value you passed to The solution here might be just updated to v1.4 as I have just optimized the Hope that helps! |
Beta Was this translation helpful? Give feedback.
-
Hi again @edmundhung 👋 Thanks a lot for your detailed answer — and for the incredible quality of Conform, it's been a real pleasure working with it 👏 We eventually decided to go with a slightly different approach using Here’s the full implementation we ended up with: "use client";
[...]
import { FieldMetadata, FormId, useFormMetadata } from "@conform-to/react";
[...]
interface MultipleEmailFieldProps {
meta: FieldMetadata<string[]>;
label?: string;
placeholder?: string;
formId: FormId<createLaboratorySchemaType>;
}
export default function MultipleEmailField({
meta,
label = "Emails de notification",
placeholder = "Ajouter un email",
formId,
}: MultipleEmailFieldProps) {
const form = useFormMetadata(formId);
const emails = meta.getFieldList();
console.log({ emails });
const [inputValue, setInputValue] = useState("");
const [inputError, setInputError] = useState("");
const insertRef = useRef<HTMLButtonElement>(null);
const isValidEmail = (email: string) =>
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
const handleAdd = () => {
const trimmed = inputValue.trim();
if (!isValidEmail(trimmed)) {
setInputError("L'adresse email est invalide");
return;
}
setInputError("");
// Create dynamically hidden email fields
const hiddenInput = document.createElement("input");
hiddenInput.type = "hidden";
hiddenInput.name = `${meta.name}[${emails.length}]`;
hiddenInput.value = trimmed;
const formElement = insertRef.current?.form;
if (!formElement) return;
formElement.appendChild(hiddenInput);
insertRef.current?.click();
formElement.removeChild(hiddenInput);
setInputValue("");
};
return (
<div className="space-y-2">
{label && <label className="block text-sm font-medium">{label}</label>}
<div className="flex gap-2">
<Input
type="email"
value={inputValue}
placeholder={placeholder}
onChange={(e) => {
setInputValue(e.target.value);
setInputError("");
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
handleAdd();
}
}}
aria-invalid={!!inputError}
className="w-[250px]"
/>
<Button type="button" onClick={handleAdd}>
Ajouter
</Button>
<button
type="submit"
ref={insertRef}
{...form.insert.getButtonProps({ name: meta.name })}
className="hidden"
/>
</div>
{inputError && <ErrorField message={inputError} />}
{meta.errors && typeof meta.errors === "string" && (
<ErrorField message={meta.errors} />
)}
<ul className="flex flex-wrap gap-2">
{emails.map((emailField, index) => (
<li
key={emailField.key}
className="flex items-center gap-1 bg-muted px-2 py-1 rounded-full"
>
<input
type="hidden"
name={emailField.name}
value={emailField.value}
/>
<span className="text-sm">{emailField.value}</span>
<button
type="submit"
{...form.remove.getButtonProps({
name: meta.name,
index,
})}
>
<X size={14} className="cursor-pointer text-gray-900" />
</button>
</li>
))}
</ul>
</div>
);
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Describe the bug and the expected behavior
Hi 👋 and thanks a lot for Conform — it's a fantastic form library and a pleasure to work with!
I'm encountering an issue with custom input components and nested object validation, and I’m not sure if I’m missing something or hitting a limitation.
❓ Context
I’m building a multi-step form using Conform.
One of my steps handles a
preferences
object, validated via Zod.Inside it, there's a conditional field:
preferences.emails
, which becomes required ifpreferences.notificationTerminee
istrue
.The field is handled via a custom component (
MultipleEmailField
) usingunstable_useControl
.Conform version
v1.0.0
Steps to Reproduce the Bug or Issue
🔧 Setup summary
1. Schema
2 Relevant parts of
MultipleEmailField.tsx
3. In my parent component:
🧪 Problem
When submitting the step with
notificationTerminee = true
andemails = []
, the error appears correctly.If I then add an email (
control.change([...])
), even with:form.update({ preferences: { emails: [...] } })
blur
manually on the<select>
elementcontrol.blur()
➡️ The validation does not re-run, and the error does not disappear — even though the field now has a valid value.
This log shows the correct update is being sent:
But in the
superRefine
logs:So
emails
is somehow still seen as empty.🧪 Additional Observations
emails = []
and getting the expected error:validate preferences []
still logs an empty array.SwitchField
), or if I re-submit the form, theemails
array is correctly seen as filled and the error disappears.🙏 Help requested
form.update()
/control.change()
calls?Thanks again for your work — the dev experience with Conform is great !
What browsers are you seeing the problem on?
No response
Screenshots or Videos
No response
Additional context
No response
Beta Was this translation helpful? Give feedback.
All reactions