如何将 Material UI 数据传递给 Formik?

How to pass Material UI data to Formik?

我正在尝试将 Material UI 'Select' 添加到我的 Formik 组件,但无法将值传递给 Formik 的初始值。

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>

如何解决这个问题?我似乎不知道如何正确获取 Material UI 的值以将它们添加到 Formik。

对于material ui,你可以使用这个很棒的库 https://github.com/stackworx/formik-material-ui

这是他们的示例代码和框 https://codesandbox.io/s/915qlr56rp?file=/src/index.tsx

如果你不想使用他们的库,你可以使用 Formik 的 component prop 来使用你的自定义组件


根据您的评论请求,我已经在 codesandbox 上编写了代码 https://codesandbox.io/s/react-formik-material-ui-select-huzv7?file=/src/App.js

我不确定为什么你有 formik 值的状态变量。这些由 formik 处理。我们不需要手动处理它们。

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>
  );
}