formik icon indicating copy to clipboard operation
formik copied to clipboard

Add meta prop to Field, FastField

Open Dremora opened this issue 7 years ago • 33 comments

Feature

Current Behavior

<Field> component, when using with a custom component or render prop, passes down the following structure to the component being rendered: { field: { name, onBlur, onChange, value }}. Extraction of touched and error for a particular field has to be done manually. This becomes quite painful when dealing with deeply nested fields. For instance, when accessing errors.foo.bar, one needs first to check the existence of errors.foo: errors.foo && errors.foo.bar.

Desired Behavior

Pass down the following structure: { field: { error, name, onBlur, onChange, touched, value }}.

Info

There is at least one caveat: <input> and other HTML elements should not receive those extra properties. It might make sense to only implement this for render prop.

Dremora avatar Jan 12 '18 17:01 Dremora

My plan is to add a meta prop that holds these values so that ppl can still spread field over an input

jaredpalmer avatar Jan 12 '18 20:01 jaredpalmer

Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.

stale[bot] avatar Aug 15 '18 17:08 stale[bot]

Not using formik anymore, and this was actually one of the reasons for switching. But I believe this is still on the roadmap. Any chance of doing this as part of #828?

Dremora avatar Aug 15 '18 21:08 Dremora

Yes for sure.

jaredpalmer avatar Aug 16 '18 20:08 jaredpalmer

https://github.com/jaredpalmer/formik/pull/579

prichodko avatar Aug 17 '18 09:08 prichodko

Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.

stale[bot] avatar Oct 16 '18 09:10 stale[bot]

Pin

jaredpalmer avatar Oct 16 '18 11:10 jaredpalmer

What about dirty by field?

I'd like to validate my field against my schema before the field is touched.

lourenci avatar Mar 14 '19 12:03 lourenci

In the documentation here: (https://jaredpalmer.com/formik/docs/api/fieldarray) it says as of

Formik v0.12 / 1.0, a new meta prop may be added to Field and FieldArray

However, according to this that field is instead earmarked for v2. Is this already available somewhere or is the documentation incorrect?

IronSean avatar May 29 '19 18:05 IronSean

It's already in v2.

jaredpalmer avatar May 29 '19 19:05 jaredpalmer

Can we not also spread the meta for the field onto the component here: https://github.com/jaredpalmer/formik/blob/next/src/Field.tsx#L189

I find it that I have to use the useField hook in order to do everything I want rather than just passing custom Input tag into the as prop of Field because i need access to the meta for additional css className rendering.

I wasn't understanding the "backwards compat" comment about the legacy component prop. If that comment holds true we should be able to pass it into the as prop.

GoPro16 avatar Jun 13 '19 13:06 GoPro16

Yeah I have noticed this myself during v2 usage.

jaredpalmer avatar Jun 13 '19 17:06 jaredpalmer

@jaredpalmer can you help me understand why meta isn't passed into component?

bschnelle avatar Jan 07 '20 16:01 bschnelle

Backwards compat

jaredpalmer avatar Jan 07 '20 17:01 jaredpalmer

can you elaborate? the docs state pretty clearly that meta is made available to the component, but then it doesn't show up and only after digging into the code is it obvious why it isn't received....just curious why backwards compatibility trumps in this situation

bschnelle avatar Jan 07 '20 18:01 bschnelle

That must be a bug then. Can you fix in the code?

jaredpalmer avatar Jan 07 '20 18:01 jaredpalmer

It is written incorrectly in the docs. meta is not passed to the component. I believe it should be crossed out and marked as deprecated.

benesva4 avatar Jan 18 '20 01:01 benesva4

meta is not passed to my Input component as props, tried as per document <Field component={Input} /> .

Since there are many issues are reported, do we have option to access field error in Field rather than look into form error?

meta should be passed to the component of the field! It contains field-level data and fields need to be able to easily access field-level data.

We have Field components that are also used outside of Formik forms. With redux-form, we could easily "plug & play" the required stuff into the field's input { value, onChange } and meta props. Migrating to Formik now and I can't believe I need to access the form prop of the field to get validation data. There's kinda the same problem with onChange. With redux-form it was onChange(value), which became onChange(event). If you want to do some processing on the field value before passing it to the form via onChange, you need to hack it as onChange({ ...event, target: {...event.target, value: VALUE } }). It was so much easier to just pass as onChange(value).

sandorvasas avatar Apr 18 '20 13:04 sandorvasas

I was pretty surprised myself the meta data wasn't in there, despite the documentation saying it should, but I think I found a decent workaround for now, querying the form is pretty easy. Example:

interface MyFieldProps extends FieldProps {
    type:string
    label:string
}
const WrappedInputField = (props: MyFieldProps) => {
    const meta = props.form.getFieldMeta(props.field.name); // <-- the workaround.
    return (
        <Form.Group as={Col}>
...

gordonjl avatar Apr 23 '20 16:04 gordonjl

Switched to useField for custom components, but lost some time wondering why i'm not getting the meta as described in the docs. This use case should either be removed the docs or get fixed.

FREEZX avatar Apr 26 '20 17:04 FREEZX

@FREEZX field-level meta should be the second item in the Tuple returned by useField. Form meta, however, must be accessed from useFormikContext.

const [field, meta] = useField(props); 

If meta, above, is not being passed for you, you should open a new issue. Please include a code sandbox repro if this is the case.

The issue above is specifically about meta not being passed to a component via <Field component={MyComponent} />

johnrom avatar Apr 26 '20 18:04 johnrom

@FREEZX field-level meta should be the second item in the Tuple returned by useField. Form meta, however, must be accessed from useFormikContext.

const [field, meta] = useField(props); 

If meta, above, is not being passed for you, you should open a new issue. Please include a code sandbox repro if this is the case.

The issue above is specifically about meta not being passed to a component via <Field component={MyComponent} />

Sorry, seems like i wasn't clear. First i tried <Field component={MyComponent} /> and then i realised meta was not being passed in props. Lost time trying to find the cause and trying a bunch of versions only to realise it wasn't working even in 2.0.0. Switched to useField, everything's fine there.

FREEZX avatar Apr 26 '20 18:04 FREEZX

Hi, I found this same issue, <Field component={MyComponent} /> is not passing the field prop.

While if I use const [field, meta] = useField(props); , since I'm not using field variable, it keeps giving me the warning field is defined but never used, which is not what I expect. 😥

It must indicate 2 vars, so the second can be matched with field meta props. Otherwise, I cannot get the correct prop (which is meta.error && meta.touched ) I want to use.

flora8984461 avatar Jan 29 '21 02:01 flora8984461

@flora8984461 you should be able to resolve that warning with the slightly odd syntax: const [, meta] = useField(props);. You don't have to assign each variable during destructuring, you can skip it with the comma.

Or you can prefix field with an underscore. Finally, you can either remove the no-undefined eslint rule, or disable eslint for that line using a comment // eslint-disable-next-line (not recommended).

johnrom avatar Jan 29 '21 15:01 johnrom

@johnrom Thanks a lot!

flora8984461 avatar Jan 29 '21 22:01 flora8984461

Solution form @gordonjl snippet is better than useField, since useField hooks you into context and you'll have problem with unnecessary rerenders.

Hajzenberg avatar Apr 12 '21 21:04 Hajzenberg

V3 will expose useFieldMeta(name). It is the same as getFieldMeta, but as a hook.

I think we should still revisit why fieldMeta isn't being passed automatically, since we have already retrieved that data in Field.

johnrom avatar Apr 12 '21 22:04 johnrom

I'm trying to migrate a big project from redux-form to Formik. This meta field not being present in the custom component, especially while the documentation implies it should be for some reason is really a pain! Also, this issue being open from 2018 really makes me doubt to choose Formik.

ngerritsen avatar Jul 23 '21 12:07 ngerritsen

I'm trying to migrate a big project from redux-form to Formik. This meta field not being present in the custom component, especially while the documentation implies it should be for some reason is really a pain! Also, this issue being open from 2018 really makes me doubt to choose Formik.

Same thing, migration from redux-form, but workaround from @gordonjl helped to me. Just add const meta = props.form.getFieldMeta(props.field.name); to your field constructor or any function which parse meta prop.

pokinbara-german avatar Aug 20 '21 19:08 pokinbara-german