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

my link to code

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

 validationSchema: Yup.object().shape({
      skill: Yup.object().shape({
        value: Yup.string().required(),
        label: Yup.string().required()
      })
    }),

当用户 Select 任何选项时,我希望它将选项保存为{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`props 自定义等价性测试.

    警告:props 类型失败:提供给`ForwardRef(Textfield)`的props `helperText`无效,应为ReactNode.

我正在try 构建可重复使用的自动完成组件,以便能够以{Label,Value}的形式获得选定值,而不会出现任何错误,并能按预期工作. 我不确定我的确认是不是正确的方式.我只想让用户 Select 一个选项.

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

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

 validationSchema: Yup.object().shape({
  skill: Yup.string().required()
}),

推荐答案

这是因为技能列表中没有{Label:‘’,Value:‘’}这样的初始值.因此在isOptionEqualToValue中,它将返回FALSE

只需删除isOptionEqualToValue属性,然后在值中判断是否存在具有该值选项,如果没有设置为空

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

在自动完成中:

<Autocomplete
     
      value={getValueFromOptions(field.value)}
    ...

或判断field.value是否具有值,否则为空

  <Autocomplete
         
      value={Boolean(field.value?.value) ? field.value : null}
    ...

另一个错误来自Show Error Message,因为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}
          />
        );
      }}

另一个错误来自于显示错误消息,它显示‘skill.value是必填字段’,所以我只是在YUP验证中添加了新消息

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

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

Reactjs相关问答推荐

滚动事件监听器在Next.js客户端组件中不触发

使用REACT-RUTER-DOM链接仅更新一个搜索参数

Reaction Google Maps API无法获取标题

如何使用TouchStart/TouchEnd在Table ReactJS中交换位置?

如何动态地改变<; Select >;React和Tailwind元素?

有没有办法在 React Router v6 中的路由匹配上运行一些逻辑/功能?

找不到名称setCometChat

React 为什么标签导致 onClick 事件运行 2 次?

Mui 在 TextField 标签上添加工具提示显示两个工具提示框

React-router-dom的链接不改变路由(ReactRouter6)

如何渲染子路径并触发react 路由父加载器?

在按钮单击中将动态参数传递给 React Query

使用 map 循环浏览列表列表中的列表并显示它们

如何禁用 redux-toolkit 的不可序列化值测试警告?

作为单个变量的 React 组件是否比 memoized 组件渲染得更快?

无法读取未定义的react native 的属性参数

如何修复 Next.js 13 中类型 AppRouterInstance 上不存在 x?

Cypress - 在继续之前等待下一个按钮重新出现

用 scss 覆盖 MUI

加密 Django Rest Framework API 响应 + 解密响应应用程序中的响应