Closed AlexanderKulia closed 2 months ago
Have you tried using useEffect
?
export const MyForm = () => {
const [value, setValue] = useControlField(
"myField",
"myForm"
);
useEffect(() => {
// Now we can update the value of the field
// for whatever reason we need.
setValue("Some value");
});
return (
<ValidatedForm validator={myValidator} id="myForm">
<MyInput
name="myField"
// This assumes your input component
// has a `value` and `onChange` prop
value={value}
onChange={(e) => setValue(e.target.value)}
/>
</ValidatedForm>
);
};
Example in here: https://www.remix-validated-form.io/reference/use-control-field
I'm not quite sure what the example demostrates. I've added useEffect
to my example repo and it does not seem to do anything regardless of how I set it up. In the particular example in the docs useEffect
is executed on every render (deps array is missing) which does not make sense and leads to infinite recursion
P.S. I had a small mistake in my initial example: value
and onChange
were missing. It's corrected now, but it doesn't change the fact that the value is undefined
on first render. Moreover, now I get this
I consider it a bug as well. The workaround is to read the defaultValue
from useField
and set the form element value as value={value ?? defaultValue}
where value
would be read through useControlField
.
This happens only when using useControlField
outside the context of the form itself. This hook has the same limitations mentioned in the "Other Considerations" section on this page. Though admittedly it doesn't look like I documented that anywhere.
I think a potential API improvement we could make here is to allow passing a default value directly into the hook like you mentioned.
But this is more of an intentional (if unfortunate) trade-off of the current API, rather than a bug. If you think about it, in code that looks like this, it's impossible for the useControlField
hook to know anything about the default values of the form.
const { defaultValues } = useLoaderData();
const [value, setValue] = useControlField("myField");
return (
<ValidatedForm
defaultValues={defaultValues}
// ...etc
/>
)
There are 3 main ways to fix the issue your observing.
const [firstName = defaultValues.firstName, setFirstName] = useControlField("firstName");
setFormDefaults
instead of the defaultValues
propexport const loader = async () => {
return setFormDefaults(formId, {
firstName: "alex",
lastName: "k",
});
};
useControlField
inside the formconst ControlledInput = (props) => {
const [value, setValue] = useControlField(props.name);
return (
<ValidatedInput
value={value}
onChange={e => setFirstName(e.target.value)}
{...props}
/>
);
}
Which packages are impacted?
remix-validated-form
@remix-validated-form/with-zod
@remix-validated-form/with-yup
zod-form-data
What version of these packages are you using?
Please provide a link to a minimal reproduction of the issue.
https://github.com/AlexanderKulia/use-control-field-example
Steps to Reproduce the Bug or Issue
yarn install
yarn dev
undefined
before its values changes to "alex"Expected behavior
I expected that the field's initial value is set to whatever is passed in
defaultValues
similar touseState<string>("alex")
. Am I doing something wrong? Because with this behavior I have to change the type tostring | undefined
and handleundefined
which is annoying in complicated dynamic formsScreenshots or Videos
No response
Platform
Additional context
No response