使用 Material UI 以嵌套形式传递 Formik 输入值

Passing Formik input values in nested forms using Material UI

我目前在使用带有 MaterialUI 表单的 Formik 时遇到问题。具体来说, 我在使用 Material UI 以嵌套形式传递 Formik 输入值时遇到问题,并且遇到 Formik.handleChange 将值从数字更改为字符串的小问题。

我在 Material UI 中有多个用 Stepper 组件拆分的表单。由于我仍在学习,我尝试将 Formik 包裹在其中一个步骤上(稍后我将包裹整个步进器)。外观如下:

          {activeStep === 0 && (
            <Formik
              initialValues={initialValues}
              validationSchema={validationSchema}
              onSubmit={(values, { setSubmitting }) => {
                setTimeout(() => {
                  alert(JSON.stringify(values, null, 2));
                  setSubmitting(false);
                }, 400);
              }}
            >
              {formik => (
                <form onSubmit={formik.handleSubmit}>
                  <div className="col-xl-6">
                    <Portlet fluidHeight>
                      <PortletHeader title="Incident Type" />
                      <PortletBody>
                        <IncidentSelect formik={formik} />
                      </PortletBody>
                    </Portlet>
                  </div>
                </form>
              )}
            </Formik>
          )}

问题出在 IncidentSelect 表单内部,Formik handleChange 似乎没有更改所选 radioButton。当我在 Chrome 中使用 React Developer Tools 检查时,似乎 Formik.handleChange 正在将值从 0 更改为“0”。我该如何解决这个问题?

还有,继tutorial, I'm unsure how I can abstract my components? Note that DateTimePicker is using material-ui/pickers。我不确定如何将值传递给 Formik。

感谢任何帮助。

谢谢

function IncidentSelect(props) {
  const [value, setValue] = React.useState("female");
  const handleRadioChange = e => {
    console.log(props.formik.getFieldProps("incidentType"));
    setValue(e.target.value);
  };

  return (
    <>
      <FormControl component="fieldset">
        <FormLabel component="legend" required>
          Incident Type:
        </FormLabel>
        <RadioGroup
          aria-label="Incident Type"
          name="incidentType"
          value={value}
          onChange={handleRadioChange}
          {...props.formik.getFieldProps("incidentType")}
        >
          <FormControlLabel
            value={0}
            control={<Radio />}
            label="Injury To Guest"
          />
          <FormControlLabel
            value={1}
            control={<Radio />}
            label="Injury To Worker"
          />
          <FormControlLabel
            value={2}
            control={<Radio />}
            label="Incident / Accident"
          />
          <FormControlLabel
            value={3}
            disabled
            control={<Radio />}
            label="OSH / Kids Camp"
          />
        </RadioGroup>
      </FormControl>
      <DateTimePicker
        label="Signed Date"
        variant="outlined"
        className={classes.margin}
        value={selectedDate}
        onChange={handleDateChange}
      />
    </>
  );
}

tutorial 中所述,更容易抽象您要使用的组件。让您有机会稍后在您的应用程序和更易读的代码中重用它们。

Formik 为您提供useFields API 通过钩子获取字段的道具。 useFields 正在寻找你的组件的 name 属性来找到对应的字段。

因此RadioGroup可以从MaterialUI中提取如下:

export const IncidentRadioButton = ({ options, ...props }) => {
  const [field, meta] = useField(props);
  return (
    <>
      <RadioGroup {...field} {...props}>
        {options.map((option, index) => (
          <FormControlLabel
            control={<Radio />}
            label={option.name}
            value={option.value}
            key={index}
          />
        ))}
      </RadioGroup>
      {meta.touched && meta.error ? (
        <div className="error">{meta.error}</div>
      ) : null}
    </>
  );
};

然后你可以使用 options 属性来相应地放置你的数据