Differences from Final Form
The project has a number of differences in working with the Final Form.
Not only form
In the Final Form you can do most things using form
.
effector-final-form provides several entities:
const { $, api } = createForm<{ firstName: string }>({
onSubmit: onSubmitMock,
subscribeOn: ['initialValues', 'values'],
});
form.$ no undefined
values
Values of some FormState properties are forcibly replaced by null to avoid a situation where the derived from form.$
may contain undefined.
List of values:
- active
- errors
- modified
- submitErrors
- touched
- visited
field.$ no undefined
values
Values of some FieldState properties are forcibly replaced by null to avoid a situation when yours derived $
from field.$
may contain undefined.
api.revalidateFx
Not presented in Final Form.
Triggers form revalidation. Can be useful when the form validation function depends on dynamic parameters (e.g. store value)
const setError = createEvent<string>();
const $error = createStore<string>('');
sample({ clock: setError, target: $error });
sample({ clock: setError, target: api.reValidateFx });
const validationFx = attach(() => {
effect: ({ fields, error }) => {
if (fields.firstName.length <= 2) {
return { firstName: error }
}
},
source: $error,
mapParams: (fields, error) => ({ fields, error })
})
setError('Incorrect value');
field.api.setValidationFn
Not presented in Final Form.
Allows you to dynamically set validation function. Uses effect.use
under the hood.
api.setSubmitFn
Not presented in Final Form.
Allows you to dynamically set submit function. Uses effect.use
under the hood.
createForm.initialValues
You can not pass undefined initial values in createForm
.
But it is possible to provide them on api.registerField
.
const form = createForm<{ name: string }>({
onSubmit: () => {},
});
form.api.registerField({
name: 'name',
initialValue: 'John',
...
})
form
& field
subscriptions
To subscribe to changes in a form or field, you should pass the subscribeOn
parameter.
Values not included in subscribeOn
will be specified in the subscription with the value false.
Except
values
of fields.
In the effector-final-form you can not create many subscribers
with different subscriptions
.
const { api } = createForm<{ firstName: string }>({
onSubmit: onSubmitMock,
subscribeOn: ['initialValues', 'values'],
});
api.registerField({
name: 'firstName',
subscribeOn: ['active'],
});
form.isValidationPaused()
It is a way to find out if validation currently paused.
// Final Form
form.isValidationPaused(); // boolean
// effector-final-form
form.$.map((s) => s.isValidationPaused); // Store<boolean>
form.registerField()
In the Final Form it is a way to register a new field and subscribes to changes to it.
In the effector-final-form you can not set a subscriber
.
// Final Form
form.registerField('firstName', () => {}, { active: true }, config: { initialValue: 'John' });
// effector-final-form
api.registerField({name: 'firstName', subscribeOn: ['active'], initialValue: 'John' })
form.getState()
getState()
gives rise to difficult to debug imperative code and kind of race condition. Prefer declarative sample to pass data from store and attach for effects
It is a way to get the current state of the form without subscribing.
// Final Form
const formState = form.getState();
// effector-final-form
const formState = form.$.getState();
form.getFieldState()
It is a way to get the state of a specific field.
// Final Form
const firstNameState = form.getFieldState('firstName');
// effector-final-form
const $firstName = $fields.map((fields) => fields.firstName);
form.subscribe()
It is a way to ubscribes to changes to the form.
In the effector-final-form you can not create many subscribers
with different subscriptions
.
const subscriber = () => {};
// Final Form
form.subscribe(subscriber, { active: true });
// effector-final-form
sample({ clock: form.$, target });