Reputation: 65
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:
Upvotes: 2
Views: 1139
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;
Upvotes: 0
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