formik icon indicating copy to clipboard operation
formik copied to clipboard

TypeError: Cannot read property 'validate' of undefined

Open stephanie-saretsky opened this issue 5 years ago • 17 comments

❓Question

I am getting the error TypeError: Cannot read property 'validate' of undefined when running a chai-enzyme test, followed by the warning: console.warn node_modules/tiny-warning/dist/tiny-warning.cjs.js:13 Warning: Formik context is undefined, please verify you are calling useFormikContext() as child of a <Formik> component.

Any help would be appreciated, I've also posted in the Discord channel but some other people had the same question but no response, so I thought I'd open an issue since it was easier to post more code here. Thanks!

This is the render of my formik component:

   const { formInfo, children, validationSchema, bindSubmitForm } = this.props;
   const validation = Yup.object(validationSchema);
   return (
     <Formik
       initialValues={formInfo}
       /* tslint:disable-next-line:jsx-no-lambda jsx-no-multiline-js */
       onSubmit={() => {
       }} // onSubmit is a required prop for Formik to work but we use our own submit in the parent component
       validationSchema={validation}
     >
       {/* tslint:disable-next-line:jsx-no-multiline-js */}
       {(formik) => {
         bindSubmitForm(formik.submitForm);
         return (
           <div className="common-form-page-container">
             <div className="common-form-container">
               <Form translate={'yes'}>
                 {children(formik)}
               </Form>
             </div>
           </div>
         );
       }}
     </Formik>
   );
 }
}

CarouselInput is the component I am testing:
formTemplate = (formik) => {
   const { banner, bannerIndex } = this.state;
   return(
     <React.Fragment>
       <FormSection title="Write It">
         <FormRow>
           <FormColumn>
             <FormInput
               required={false}
               field="carousel"
               formType={HTML_TAGS.CUSTOM}
               /* tslint:disable-next-line:jsx-no-lambda jsx-no-multiline-js */
               render={() => {
                 const handleContentIndex = async (index) => {
                   this.setState({
                     bannerIndex: index,
                   });
                 };
                 return (
                   <CarouselInput
                     formInfo={banner.content}
                     onChange={this.handleOnChange}
                     newItem={this.addNewTab}
                     handleIndex={handleContentIndex}
                     carouselSlideIndex={bannerIndex}
                     children={(onChange, content) => <BannerCarouselForm onChange={onChange} content={content} />}
                   />
                 );
               }}
             />
           </FormColumn>
         </FormRow>
       </FormSection> 
 </React.Fragment>
)}

And this is the test:
 it('should add new slide on click', () => {
   const tree = shallow(<CommonFormWrapper />);

   const component = mount(
     <CarouselInput
       formInfo={content}
       onChange={this.handleOnChange}
       newItem={this.addNewTab}
       handleIndex={handleIndex}
       carouselSlideIndex={0}
       /* tslint:disable-next-line:jsx-no-lambda */
       children={(onChange, content) => <BannerCarouselForm onChange={onChange} content={content} />}
     />
   );
   tree.find(component).dive().find('.add-slide-button').simulate('click', { persist: () => {}, });
   expect(newItem).to.have.been.calledOnce;
 });

stephanie-saretsky avatar Feb 14 '20 20:02 stephanie-saretsky

I have the same problem. But it happens when i manually execute validateField function. Did you find solution?

TotallWAR avatar Feb 26 '20 12:02 TotallWAR

I have that issue when I extract a component and test it on its own. In my case I am using FieldArray and I get that error. It is fixed when I have Formik acting as a wrapper as if it is part of the actual form.

zsid avatar Mar 05 '20 16:03 zsid

I use useFormik hook. My validation schema is valid, but I have the same problem when I call validateField manually.

Badyanchik avatar Mar 18 '20 14:03 Badyanchik

Having the same issue on latest version of Formik.

vitorlimadev avatar Apr 06 '20 17:04 vitorlimadev

Having the same issue

k290 avatar Apr 20 '20 13:04 k290

It seems like in most cases, the Form Fields aren't being wrapped in a FormikProvider (like <Formik />) when testing.

@Badyanchik validateField is kind of interesting. Basically, you'd still need to wrap a <Field /> in a <FormikProvider /> in order to register the field with Formik's fieldRegistry and instantiate the field-level validation callback. You might be able to get away with manually calling formik.registerField, but Formik relies heavily on Context so you may run into other issues if you try to circumvent context.

That said, any and all codesandbox repros are welcome so I can look closer at these issues!

johnrom avatar Apr 20 '20 14:04 johnrom

I'm using react native's TextInput got the same error with I tried to call validateField(). Probably because there's not <Field> wrapped?

resting avatar Apr 26 '20 13:04 resting

Formik component or another FormikContext provider must appear above your useField hook or Field component in the component hierarchy, even when testing.

If you're using useField, you don't need Field, but you still need Formik.

johnrom avatar Apr 26 '20 16:04 johnrom

I am also getting same error when using validateField() So, for the time being i am using validateForm()

GuppuBoss avatar May 20 '20 10:05 GuppuBoss

Same error

jvitorr avatar Jun 10 '20 22:06 jvitorr

@jvitorr did you try https://github.com/jaredpalmer/formik/issues/2291#issuecomment-619577563 ?

johnrom avatar Jun 11 '20 14:06 johnrom

Instead of validateField() you can use setFieldTouched() which can also trigger validation

owystyle avatar Sep 27 '20 17:09 owystyle

I have solve this by putting ref={this.formRef} in form tag, formRef = React.createRef() i have use in class

abhishekg-cashify avatar Aug 29 '21 14:08 abhishekg-cashify

I have the same problem. but I'm using the < Formik > and < Form > tags when the validation scheme is added the form stops sending the values

CharlieBellow avatar Dec 06 '22 19:12 CharlieBellow

When i uses tag <Formik></Formik>, I use Field-level validation with validate name property.

See more in: docs

       const validation = Yup.object(validationSchema);
       return (
           <Formik  validate={validation}/>
        )

thuansilva avatar Jan 13 '23 16:01 thuansilva

<FormikProvider value={formik}> </FormikProvider>

you need wrap everything inside this and pass const formik = useFormik(); to it

pooooriya avatar Apr 22 '23 08:04 pooooriya

@owystyle https://angularjs-routing.github.io/matter83/

minimax-warlike avatar Oct 20 '25 21:10 minimax-warlike