Can't get Formik form to work with Material UI

Viewed 25

I'm struggeling with making my Formik form work. Here a part of my code:

import { Formik, Form as FormikForm, Field } from "formik";
import {TextField} from "@mui/material";

<Formik
        initialValues={{
            name: "test",
        }}
        onSubmit={this.onSubmit}
        >
            {({ values,handleChange }) => (
                <FormikForm>
                                
                            <Field
                                component={TextField}
                                name="name"
                                label="Name"
                                fullWidth
                                
                            ></Field>
                                    
                            <Button
                                color="success"
                                variant="contained"
                                type="submit"
                                onClick={() => {
                                    console.log(values);
                                }}
                            >
                                Erstellen
                            </Button>
                                    
                </FormikForm>
        )}
</Formik>

It seems like its having trouble connecting the values state to the Field value, since the initialValue isn't displayed in the names field. When i submit, it logs {name: 'test'} to console, no matter what i enter in the input field.

Edit 1:

I also have a very similar form that works. The only difference between the two that i can think of is: the working one is a .jsx while this one is .tsx. Dont know if that has anything to do with it.

2 Answers

According to the Field documentation you need to spread the field and pass it to the component like this:

import { Formik, Form as FormikForm, Field } from "formik";
import { Button, TextField } from "@mui/material";

const MuiTextField = ({ field, form, ...props }) => {
  return <TextField {...field} {...props} />;
};

const MyComponent = () => {
  return (
    <Formik
      initialValues={{
        name: "test"
      }}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      {({ values, handleChange }) => (
        <FormikForm>
          <Field
            component={MuiTextField}
            name="name"
            label="Name"
            fullWidth
          ></Field>

          <Button
            color="success"
            variant="contained"
            type="submit"
            onClick={() => {
              console.log(values);
            }}
          >
            Erstellen
          </Button>
        </FormikForm>
      )}
    </Formik>
  );
};

export default MyComponent;

You can take a look at this sandbox for a live working example of this solution.

Like Ahmet pointed out, the problem seems to be that the field prop needs to be spread (see his answer). However i found, that using as instead of component works too and doesnt need spreading.

 <Field
       as={TextField}
       name="name"
       label="Name"
       fullWidth
 ></Field>
Related