首页 > 解决方案 > 使用 Material UI 在嵌套表单中传递 Formik 输入值

问题描述

我目前在将 Formik 与 MaterialUI 表单一起使用时遇到问题。具体来说,我在使用 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 表单内部,FormikhandleChange似乎没有更改 selected radioButton。当我在 Chrome 中使用 React Developer Tools 进行检查时,似乎Formik.handleChange将值从 0 更改为“0”。我该如何解决?

另外,按照教程,我不确定如何抽象我的组件?请注意, DateTimePicker 正在使用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}
      />
    </>
  );
}

标签: reactjsformikformik-material-ui

解决方案


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

Formik 为您提供useFieldsAPI 以通过 hooks 获取字段的 props。useFields正在寻找name你的组件的 props 来找到对应的字段。

因此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道具相应地放置您的数据


推荐阅读