final-form / final-form/react-final-form
Massive performance issue with validation + missing access to meta data in validation
- Dominant language
- JavaScript
- Stars
- 7.4k
- Forks
- 497
- PR merge metrics
- No merged PRs in 30d
Description
### Are you submitting a **bug report** or a **feature request**?
Bug Report
### What is the current behavior?
When using field level validation the validation method is called independently from whether a message is shown at all (because it is only rendered when the form field was touched.
This is how our custom Field wrapper looks like:
```js
return ( {
if ((!value || value === '') && props.required) {
return (
);
}
if (props.validate) {
return props.validate(value, props.name, values);
}
}}>
{({input, meta}) => (
{props.required && ' *'}
{meta.error &&
meta.touched && (
{meta.error}
)}
)}
)
```
It shows that the validation method runs whenever any of the fields changes. With our form which used `final-form-array` it's pretty easy to reach 50+ form fields. In this case each of the fields is rendered whenever any of the fields are changing. And not only once, but as often as the number of fields visible at each moment.
The second issue is that this change leads to a re-rendering of all fields (a few times) as the `Field` itself is unable to know what the content is doing with the updated validation results as meta data.
I just found the `validationFields` config which seems like some manual optimization. (I figure that for most users the current default might be wrongly chosen here. That said I was happy to see this behavior is available at all - which is super useful for cross-field checks - but should probably be not the default for performance reasons.)
### What is the expected behavior?
I figure I would suggest to add some boolean flag to toggle whether all fields should be validated when another field changes. Tricky to find good names here. The long description name would be probably `validateOnOtherChanges` - but this is probably too cumbersome to use. Maybe reuse your `validateFields` and allow a value `"all"` instead of an array for defining to validate all fields.
Next I figure it would be definitely useful to offer access to meta data in the validation method. It would be helpful to have access to `meta.touched`. Otherwise I figure it would also be a good default behavior to call validation only when a field was touched before (which happens to be active anyway when the user tries submitting the form). Could also be a new prop e.g. validateUntouched which defaults to `false`.
Unfortunately some breaking changes here which would probably be on the road to 4.x.
### Sandbox Link
Not yet. Hopefully the mentioned example scenarios are a good start for now.
### What's your environment?
Chrome v64
Mac OS 10.13.3
$ grep final package.json
"final-form": "^4.3.1",
"final-form-arrays": "^1.0.4",
"final-form-calculate": "^1.0.2",
"react-final-form": "^3.1.4",
"react-final-form-arrays": "^1.0.4",
Contributor guide
Assessment
This issue has not been assessed yet.