具有自动完成功能的 Formik 材料 ui 无法按预期工作

Adi*_*ari 5 reactjs material-ui yup formik

我使用formikMaterial-ui来构建自定义自动完成组件。

我的代码链接

我使用yup添加验证以要求自动完成(用户需要选择一个选项):

 validationSchema: Yup.object().shape({
      skill: Yup.object().shape({
        value: Yup.string().required(),
        label: Yup.string().required()
      })
    }),
Run Code Online (Sandbox Code Playgroud)

当用户选择任何选项时,我希望它将选项保存为 {label,value} 而不仅仅是值,因为这样我需要将其作为对象发送到服务器。

我收到一些错误:

  1. 当我按提交时出现错误

    Objects are not valid as a React child (found: object with keys {value, label}). If you meant to render a collection of children, use an array instead.

  2. 我收到这些警告:

    MUI:提供给自动完成的值无效。没有一个选项与 `{"label":"","value":""}` 匹配。您可以使用“isOptionEqualToValue”属性来自定义相等测试。

    警告:道具类型失败:向“ForwardRef(TextField)”提供的道具“helperText”无效,需要 ReactNode。

我正在尝试构建可重用的自动完成组件,以便能够将选定的值作为 {label,value} 获取,而不会出现任何错误并按预期工作。我不确定我的验证方法是否正确。我只想让用户选择一个选项。

另外,我想问一下,我可以将对象详细信息存储到值中而不是字符串中吗?如果不是,存储对象值作为选项的最佳方式是什么?

我的 yup 模式是正确的方法吗?我应该将对象的 id 存储为值然后对其进行过滤吗?如何将值作为字符串传递给自动完成并显示在自动完成中选择的值?如果没有技能模式作为对象,我该如何做到这一点,就像字符串一样:

 validationSchema: Yup.object().shape({
  skill: Yup.string().required()
}),
Run Code Online (Sandbox Code Playgroud)

Ali*_*deh 3

这是因为初始值 {label:'' , value :''} 不在技能列表中。所以在 isOptionEqualToValue 中它将返回 false

只需删除 isOptionEqualToValue 属性并在值中检查是否存在具有该值的选项,如果没有设置为 null

  const getValueFromOptions = (value: string) => {
    return (
      options.find((option: any) => option.value === value) ?? null
    );
  };
Run Code Online (Sandbox Code Playgroud)

并在自动完成中:

<Autocomplete
     
      value={getValueFromOptions(field.value)}
    ...
Run Code Online (Sandbox Code Playgroud)

或检查 field.value 是否有值,否则为 null

  <Autocomplete
         
      value={Boolean(field.value?.value) ? field.value : null}
    ...
Run Code Online (Sandbox Code Playgroud)

另一个错误来自显示错误消息,因为 meta.error 是包含值和标签错误的对象,因此您需要显示其中之一,我将其更改为:

renderInput={(params) => {

        const errorMsg = meta.error as { value?:string }

        return (
          <TextField
            {...params}
            label={label}
            name={name}
            error={showError}
            helperText={meta.touched && errorMsg?.value}
          />
        );
      }}
Run Code Online (Sandbox Code Playgroud)

另一个错误来自显示错误消息,它显示“skill.value 是必填字段”,所以我只需在 yup 验证中添加新消息

validationSchema: Yup.object().shape({
      skill: Yup.object().shape({
        value: Yup.string().required('skill is a required field'),
        label: Yup.string()
      })
    }),
Run Code Online (Sandbox Code Playgroud)

您在这里看到纯代码: https: //codesandbox.io/s/blissful-nova-nqvxq2 ?file=/src/components/AutocompleteField.tsx