EDIT: THE IDEA BELLOW WORKS
I just noticed that the problem was in . notation of values I used. The path must be correctly converted to the same object structure as in case of tools changeValue).
Also, this code
...
const initialValues = form.getState().initialValues;
initialValues[fieldName] = fieldValue;
form.setConfig("initialValues", initialValues);
...
had to be changed to
...
const initialValues = form.getState().values;
initialValues[fieldName] = fieldValue;
form.setConfig("initialValues", initialValues);
...
as I wanted current values to be kept in the form instead of the form has to be "reinitialized".
I am using final-form for presenting a form partly generated dynamically based on the data templates and the data itself loaded from the server.
In order to generate the form and populate it with the values loaded from the server I am using custom mutator, which just sets the correct values once the form is generated and the data is loaded from the server.
Mutator works well, but I also need to set initialValues once the part of the form (based i.e. on initial value or user selected value of the combo box) is loaded and generated in order to prevent dirty state before the form is touched by the user.
Question: Is it possible to set initialValues dynamically, once the template/data is loaded in order to prevent pristine/dirty state, but also, without touching other form values and initialValues?
Please note, this is just example of children component used within the form declared in parent component (including the custom mutator). My original code is way too complex to pass it here. Maybe this code is not fully syntactically correct, maybe it would not work with checkbox, don't care too much about it - it is just an example and the question is about something else. Mutator works actually well, so please focus on initalValues.
interface Props {
fieldName: string;
fieldType: "checkbox" | "text";
fieldValue: string | boolean;
}
function DynamicFormField({
fieldName,
fieldType,
fieldValue
}: Props) {
const form = useForm();
useEffect(
() => {
// *** this is what I tried, but does not work ***
const initialValues = form.getState().initialValues;
initialValues[fieldName] = fieldValue;
form.setConfig("initialValues", initialValues);
// ***
// *** also tried ***
const initialValues = { ...form.getState().initialValues };
initialValues[fieldName] = fieldValue;
form.setConfig("initialValues", initialValues);
// ***
form.mutators.setValue(fieldName, fieldValue);
},
[fieldName, fieldValue]
)
}
return (
<Field name={fieldName}>
{({ input }) => (
{
fieldType === "checkbox" ?
(<input {...input} type="checkbox")
:
(<input {...input} type="text")
}
)}
</Field>
)
It works, please see edit.
The initialValues object must just have same structure as the values object.