formik icon indicating copy to clipboard operation
formik copied to clipboard

Rerender FastField when non-formik context props change

Open ericbiewener opened this issue 6 years ago • 9 comments

🚀 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!

ericbiewener avatar Dec 14 '18 17:12 ericbiewener

Seems like a good idea

jaredpalmer avatar Dec 14 '18 18:12 jaredpalmer

+1 to this use case, should be nice if you implement this feature. Btw thanks for Formik!

mntnv avatar Dec 18 '18 11:12 mntnv

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

smakosh avatar Dec 24 '18 05:12 smakosh

Yes, this would cause that issue.

ericbiewener avatar Dec 27 '18 00:12 ericbiewener

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.

Burize avatar Dec 24 '19 09:12 Burize

+1

satanworker avatar Mar 06 '20 10:03 satanworker

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>

andycaramba avatar Mar 24 '20 19:03 andycaramba

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;

harurang avatar Sep 19 '22 19:09 harurang

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;

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.

aprilmintacpineda avatar Oct 30 '23 11:10 aprilmintacpineda