1

我正在尝试将 Material UI 的 Autocomplete 与 Formik 一起使用。这是我编写的用于 Formik 的自定义自动完成组件。

import React from "react";
import Autocomplete from "@material-ui/lab/Autocomplete";
import TextField from "@material-ui/core/TextField";
import { fieldToTextField } from "formik-material-ui";

const FormikAutocomplete = ({ textFieldProps, ...props }) => {
  const {
    form: { setTouched, setFieldValue },
  } = props;
  const { error, helperText, ...field } = fieldToTextField(props);
  const { name } = field;

  return (
    <Autocomplete
      {...props}
      {...field}
      onChange={(_, value) =>
        setFieldValue(name, value)
      }
      onBlur={() => setTouched({ [name]: true })}
      renderInput={(props) => (
        <TextField
          {...props}
          {...textFieldProps}
          helperText={helperText}
          error={error}
        />
      )}
    />
  );
};

export default FormikAutocomplete;

这是组件的调用方式

<Field
  name="title"
  component={FormikAutocomplete}
  options={gender}
  getOptionLabel={(option) => option.title_name_long}
  textFieldProps={{
    label: "Title",
    required: true,
    variant: "outlined",
    margin: "dense",
  }}
/>

现在我打算做的是:如果我有一个像

gender=[{gender_name_short:"F",gender_name_long:"Female},{gender_name_short:"M",gender_name_long:"Male}]

我希望自动完成下拉菜单显示男性、女性的选项。但是我希望formik状态从下拉列表中选择后分别保存M,F。目前整个对象都被保存了。

如何才能做到这一点?

4

1 回答 1

1

FormikAutocomplete组件中,

  • 在自动完成的 onChange 中使用 setFieldValue
  • 用于显示,gender_name_long_getOptionLabelMaleFemale
  • 用于使用或gender_name_short_getOptionSelectedMF

最后,当你提交时,你会看到M/FMale/Female

工作演示

const gender = [
  { gender_name_short: "F", gender_name_long: "Female" },
  { gender_name_short: "M", gender_name_long: "Male" }
];
const validationSchema = object().shape({
  // genderObj: array().required("At least one gender is required")
});

const initialValues = {
  username: "abc",
  country: "",
  gender: "M",
  birthdate: null
};

const FormikAutocomplete = ({ textFieldProps, ...props }) => {
  const {
    form: { setTouched, setFieldValue }
  } = props;
  const { error, helperText, ...field } = fieldToTextField(props);
  const { name } = field;

  return (
    <Autocomplete
      {...field}
      {...props}
      onChange={(_, data) => {
        setFieldValue("gender", data.gender_name_short);
      }}
      onBlur={() => setTouched({ [name]: true })}
      // getOptionLabel={item => item.gender_name_long} //<----see here
      getOptionLabel={item => {
        // console.log( '====>' , typeof item === "string" ? props.options.find(i => i.gender_name_short === item).gender_name_long : item.gender_name_long)
        return typeof item === "string"
          ? props.options.find(i => i.gender_name_short === item)
              .gender_name_long
          : item.gender_name_long;
      }}
      // getOptionLabel={item => typeof item === 'string' ? props.options.find(i => i.gender_name_short === item).gender_name_long : item.gender_name_long}
      getOptionSelected={(item, current) => {
        return item.gender_name_short === current;
      }}
      // defaultValue={'hi'}
      renderInput={props => (
        <TextField
          {...props}
          {...textFieldProps}
          helperText={helperText}
          error={error}
        />
      )}
    />
  );
};

const SimpleFormExample = () => (
  <div>
    <h1>Simple Form Example</h1>
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      validateOnBlur={false}
      validateOnChange
      onSubmit={(values, { resetForm, setSubmitting }) => {
        console.log(values);
        resetForm();
        // setSubmitting(false);
      }}
    >
      {formik => (
        <Form>
          <Field
            name="gender"
            component={FormikAutocomplete}
            label="gender"
            options={gender}
            textFieldProps={{
              fullWidth: true,
              margin: "normal",
              variant: "outlined"
            }}
            // multiple
          />

          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);

export default SimpleFormExample;
于 2020-07-22T14:12:52.170 回答