简体   繁体   中英

How to pass Material UI data to Formik?

I am trying to add a Material UI 'Select' to my Formik component, but can't pass the values to Formik's initialValues.

const [hours, setHours] = React.useState('');
const handleHourChange = ({ target }) => {
    setHours(target.value);
};

<Formik
   initialValues={{
     price: ''   //not Material UI. Works.
     hours: hours //from Material UI
   }} 

  <Form>
     <label htmlFor={'price'}> Price </label>
     <Field
        name={'price'}
        type="text"            //this Field (not Material UI) works fine.
     />

     //...

     //the below, which is Material UI's 
     //doesn't send its values to Formik's initialValues

     <FormControl className={classes.formControl}>
        <InputLabel id="demo-simple-select-label">Hours</InputLabel>
        <Select
          name={'hours'} //I added this name prop but not sure it's making any difference
          labelId="demo-simple-select-label"
          id="demo-simple-select"
          value={hours}
          onChange={handleHourChange}>
          <MenuItem value={60}>01</MenuItem>
          <MenuItem value={120}>02</MenuItem>
        </Select>
      </FormControl>

   </Form>
</Formik>

What could be done to fix this? I don't seem to know how to properly get Material UI's values to add them to Formik.

For material ui, you can use this great library https://github.com/stackworx/formik-material-ui

Here is their sample codesandbox https://codesandbox.io/s/915qlr56rp?file=/src/index.tsx

If you don't want to use their library, you can use Formik's component prop to use your custom component


Based on your comment request, I've written the code here at codesandbox https://codesandbox.io/s/react-formik-material-ui-select-huzv7?file=/src/App.js

I'm not sure why you have state variables for formik values. Those are handled by formik. We don't need to handle them manually.

import React from "react";
import { Formik, Form, Field } from "formik";
import {
  Select,
  InputLabel,
  MenuItem,
  FormControl,
  Button
} from "@material-ui/core";
import "./styles.css";

const CustomizedSelectForFormik = ({ children, form, field }) => {
  const { name, value } = field;
  const { setFieldValue } = form;

  return (
    <Select
      name={name}
      value={value}
      onChange={e => {
        setFieldValue(name, e.target.value);
      }}
    >
      {children}
    </Select>
  );
};

export default function App() {
  /*
    You don't need to handle the formik values as state.
    Formik handles it itself
    const [hours, setHours] = React.useState("");
    const handleHourChange = ({ target }) => {
      setHours(target.value);
    };
  */

  return (
    <Formik
      initialValues={{
        price: "abcv", //not Material UI. Works.
        hours: 60 //from Material UI
      }}
      onSubmit={(values, actions) => {
        alert("values:" + JSON.stringify(values));
      }}
    >
      <Form>
        <label htmlFor={"price"}> Price </label>
        <Field
          name={"price"}
          type="text" //this Field (not Material UI) works fine.
        />

        <FormControl>
          <InputLabel id="demo-simple-select-label">Hours</InputLabel>
          <Field name="hours" component={CustomizedSelectForFormik}>
            <MenuItem value={60}>01</MenuItem>
            <MenuItem value={120}>02</MenuItem>
          </Field>
        </FormControl>
        <Button type="submit">Submit</Button>
      </Form>
    </Formik>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM