Material UI 自动完成组件的默认值为空字符串

22

当向自动完成 Autocomplete 组件传递空字符串时,它会抛出控制台警告,表示该值无效。

我该如何让这个警告消失?虽然它不会导致任何问题,但在每次重新渲染时都会在控制台中抛出警告,这非常令人恼火。我似乎唯一能够避免它的方法是将该字段的初始值设置为 null,但据我理解,这不应该是输入的默认值。

当前行为

将默认值为空字符串传递给 Autocomplete 组件时,它会抛出控制台警告,指出空字符串的值无效。

errorForGithub

期望的行为

如果传递给 Autocomplete 的值是空字符串,则不应抛出任何警告或错误。

复现步骤

以下链接展示了错误:https://codesandbox.io/s/material-demo-n0ijt

1)将空字符串传递给 Autocomplete 组件的 value 属性。


请更新您的问题并删除所有不相关的内容。这是从Material-UI GitHub页面的问题模板中复制并粘贴的。请不要在StackOverflow上使用此内容。 - Dekel
似乎这是展示我所做的和我遇到的问题的好方法。 - Gerry Blackmon
如上所述 - 仅保留相关数据(结构不重要,环境不重要等...) - Dekel
5个回答

38

您可以使用null作为初始状态,这可能会达到您想要的效果。

value={data.value || null}

如果您将其设置为未定义,则会抱怨受控组件,通过这种方式即使在使用自动完成后,我也不会收到错误信息。


2
当我使用const val = [val, setVal] = useState(null);时,将value={val}传递给组件是完美的。 - Ben
在 MUI 5+ 中,可以使用此解决方案或 isOptionEqualToValue={(option, value) => value === option || value === ''} - Pavan Jadda

11

我解决了处理输入字符串为空的情况(您没有这样做)。在您的沙盒中需要三件事:

  1. 第17行,在getOptionSelected内部,当值为空字符串时必须返回true;这样React就会选择一个选项并使警告消失。
  2. 修改第14行的getOptionLabel,处理空字符串的情况。我会按照以下方式进行:
getOptionLabel={option => option.title ? option.title : ''}

如果选项有标题,则返回标题,否则返回可视化的空字符串。

  1. 最后,修改 onChange 处理空字符串的方式如下:
onChange={(e, selectedObject) => {
    if (selectedObject !== null)
        setValue(selectedObject)
}}

总体来说:

import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";

export default function FreeSoloCreateOption() {
  const [value, setValue] = React.useState("");

  return (
    <Autocomplete
      value={value}
      id="empty-string-demo"
      options={top100Films}
      getOptionLabel={option => option.title ? option.title : ''}
      getOptionSelected={(option, value) => {
        //nothing that is put in here will cause the warning to go away
        if (value === "") {
          return true;
        } else if (value === option) {
          return true;
        }
      }}
      onChange={(e, selectedObject) => {
        if (selectedObject !== null)
            setValue(selectedObject)
      }}
      renderOption={option => option.title}
      style={{ width: 300 }}
      renderInput={params => (
        <TextField
          {...params}
          label="Default Value of Empty String"
          variant="outlined"
        />
      )}
    />
  );
}

谢谢!对于我的情况,只有标签格式化器引起了问题。将其更新为 getOptionLabel={(option) => (option && option.label)? option.label: ""} - Debojyoti
这是我的代码:getOptionLabel={option => option?.title || ''}getOptionSelected={(option, value) => value === '' || option.id === value.id} - Mauro Nidola
3
我已尝试上述解决方案。组件初始化时,下拉菜单中的所有选项都处于选中模式。我能够得到修复该问题的方法吗? - ram
这个帮了我很多,我也处于完全相同的情况。谢谢! - ScreamoIsDead

1
将此添加到自动完成功能中...
isOptionEqualToValue={(option, value) => {
    // Accept empty string
    if(value === option || value === "") { return true; }
}}

这个不行。如果值是"",它会返回所有选项都被选择的true... 如果你反转懒惰求值,它就可以工作了... if(value === option || value === "" ) { return true; } - ortonomy
user10233170 THANKS!!! - Edenco

0
  <Autocomplete className={styles['vacation-list-status']}
                        id="vacation-list-status"
                        options={vacationStatus}
                        getOptionLabel={option => option.label}
                        onChange={(event, newValue) => {
                          handleVacationStatus( 
                              newValue ? newValue.value : null
                          );
                        }}
                        renderInput={(params) => (
                           <TextField
                            {...params}
                            variant="outlined"
                            label={t('status')}
                           />
                        )}
                    />

0

一个简单的改变是过滤掉初始复位

onChange={(event, newValue, reason) => {
    if (reason === 'reset' && newValue === '') {
        // Do nothing
    }
    else {
        setValue(newValue);
    }
}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接