Muhammad Shah Sawar
Muhammad Shah Sawar

Reputation: 65

Invalid hook call. Hooks can only be called inside of the body of a function component-formik

In a simple react application I used formik hook useFormik but the browser complains about its usage at the wrong place. Here is what I've done:

import React from 'react';
 import { useFormik } from 'formik';
 
 const SignupForm = () => {
   // Pass the useFormik() hook initial form values and a submit function that will
   // be called when the form is submitted
   const formik = useFormik({
     initialValues: {
       email: '',
     },
     onSubmit: values => {
       alert(JSON.stringify(values, null, 2));
     },
   });
   return (
     <form onSubmit={formik.handleSubmit}>
       <label htmlFor="email">Email Address</label>
       <input
         id="email"
         name="email"
         type="email"
         onChange={formik.handleChange}
         value={formik.values.email}
       />
 
       <button type="submit">Submit</button>
     </form>
   );
 };
 export default SignupForm;

then I used useState hook it is working fine but this one is complaining. The complaint is:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

Upvotes: 2

Views: 1139

Answers (2)

Sagar B
Sagar B

Reputation: 204

    React v.18.0 Compatible packages for Formik with material UI (mui) needs to be get installed.
    
    Hence, This issue can be resolved using "formic-mui" package. 
    
    steps:
    
    1. need to install packages "formik formik-mui @mui/material @emotion/react @emotion/styled"
    
    2. then follow guidelines from here: [https://stackworx.github.io/formik-mui/docs/guide/getting-started][1]
    
    3. After modifications, your code will look like this:
    
     
    
     
    import * as React from 'react';
    import { Formik, Field, Form, FormikHelpers } from 'formik';
    import { Button, Grid, LinearProgress } from '@mui/material';
    import * as yup from 'yup';
    import { TextField } from 'formik-mui';
    import TextareaAutosize from '@material-ui/core/TextareaAutosize/TextareaAutosize';
    
    interface Values {
      email: string;
      password: string;
    }
    
    const CustomerDetails = () => {
      return (
        <div>
          <h1>Customer Details</h1>
    
          <Formik
            initialValues={{
              email: '',
              password: '',
            }}
            validate={(values) => {
              const errors: Partial<Values> = {};
              if (!values.email) {
                errors.email = 'Required';
              } else if (
                !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
              ) {
                errors.email = 'Invalid email address';
              }
              return errors;
            }}
            onSubmit={(values, { setSubmitting }) => {
              setTimeout(() => {
                setSubmitting(false);
                alert(JSON.stringify(values, null, 2));
              }, 500);
            }}
          >
            {({ submitForm, isSubmitting }) => (
              <Form>
                <Grid container spacing={1}>
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      name="customername"
                      type="customername"
                      label="Customer Name"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={12} sm={4}>
                    <Field
                      component={TextField}
                      type="telephone"
                      label="Telephone"
                      name="telephone"
                      fullWidth
                    />
                  </Grid>
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      type="dob"
                      label="Date of Birth"
                      name="dob"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={12} sm={4}>
                    <Field
                      component={TextField}
                      type="alttelephone"
                      label="Alt Telephone"
                      name="alttelephone"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={12} sm={4}>
                    <Field
                      component={TextField}
                      type="alttelephone"
                      label="Alt Telephone"
                      name="alttelephone"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      name="email"
                      type="email"
                      label="Email"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      name="password"
                      type="password"
                      label="Password"
                      fullWidth
                    />
                  </Grid>
    
                  {isSubmitting && <LinearProgress />}
    
                  <Grid item xs={12} sm={12}>
                    <Button
                      variant="contained"
                      color="primary"
                      disabled={isSubmitting}
                      onClick={submitForm}
                    >
                      Submit
                    </Button>
                  </Grid>
                </Grid>
              </Form>
            )}
          </Formik>
        </div>
      );
    };
    
    export default CustomerDetails;

enter image description here

enter image description here

Upvotes: 0

SlothOverlord
SlothOverlord

Reputation: 2037

I had a similar issue. It turned out that the package didn't install at all but typescript didn't detect that it was missing.

Try

rm -rf node_modules
rm package-lock.json
npm i 
npm i formik

Then check if you have it in package.json

Upvotes: 0

Related Questions