formik
formik copied to clipboard
Rerender FastField when non-formik context props change
🚀 Feature request
Current Behavior
Non-formik context props only trigger a FastField rerender if they are added or removed.
Desired Behavior
Allow FastField to rerender when non-formik context props change value. This doesn't strike me as something that is likely to produce a performance hit.
Suggested Solution
Do a shallow comparison of non-formik context props in FastField's shouldComponentUpdate
Who does this impact? Who is this for?
All the people!
Seems like a good idea
+1 to this use case, should be nice if you implement this feature. Btw thanks for Formik!
I've been trying to change the type of FastField by clicking on a button but doesn't seem to work, works fine with Field, maybe it's related to this
Yes, this would cause that issue.
Any update on this? - With current FastField's behavior there is no way to set html basic attributes (eg disabled), that changes and depends on the external props.
+1
For everyone who has encountered this issue. I have found a solution. FastField has a prop shouldUpdate in which you can define your own conditions for updating the component.
For example
const shouldComponentUpdate = (nextProps, currentProps) => {
return nextProps.name !== currentProps.name
|| nextProps.required !== currentProps.required
|| nextProps.disabled !== currentProps.disabled
|| nextProps.readOnly !== currentProps.readOnly
|| nextProps.formik.isSubmitting !== currentProps.formik.isSubmitting
|| Object.keys(nextProps).length !== Object.keys(currentProps).length
|| getIn(nextProps.formik.values, currentProps.name) !== getIn(currentProps.formik.values, currentProps.name)
|| getIn(nextProps.formik.errors, currentProps.name) !== getIn(currentProps.formik.errors, currentProps.name)
|| getIn(nextProps.formik.touched, currentProps.name) !== getIn(currentProps.formik.touched, currentProps.name);
};
<FastField { ...props } shouldUpdate={ shouldComponentUpdate }>
...
</FastField>
And if you want to tap into a prop that isn't part of the form, you use the meta prop:
<FastField
name="dateTime"
meta={{
hasWarning: props.hasWarning,
}}
shouldUpdate={shouldUpdateFastField}
...etc
const shouldUpdateFastField = (
nextProps: {meta: {hasWarning?: boolean}},
currentProps: {meta: {hasWarning?: boolean}}
) => nextProps.meta?.hasWarning !== currentProps.meta?.hasWarning;
And if you want to tap into a prop that isn't part of the form, you use the
metaprop:<FastField name="dateTime" meta={{ hasWarning: props.hasWarning, }} shouldUpdate={shouldUpdateFastField} ...etcconst shouldUpdateFastField = ( nextProps: {meta: {hasWarning?: boolean}}, currentProps: {meta: {hasWarning?: boolean}} ) => nextProps.meta?.hasWarning !== currentProps.meta?.hasWarning;
This one worked, but we don't get any typehints so I'm wondering if this is actually something supported or just experimental. There's also no mention of it on the API docs.
EDIT:
I also noticed that when you pass this props, you will override the default behavior instead of it being added on top.