reactjs Material-ui自动完成警告提供给自动完成的值无效

vojdkbi0  于 2023-04-05  发布在  React
关注(0)|答案(8)|浏览(139)

我正在使用React和material-ui..我刚刚意识到当我尝试提交表单时,Autocomplete组件会发出警告,所以我尝试做一些非常基本的事情,就像文档中一样:

let Form = props => {

  return(
        <form noValidate onSubmit={handleSubmit} >
            <Autocomplete
                id="combo-box-demo"
                options={[{id:1,name:"test"},{id:2, name:"test2"}]}
                getOptionLabel={(option) => option.name}
                style={{ width: 300 }}
                renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" />}
            />

当我尝试提交表单时,我得到以下错误:
材料-UI:提供给自动完成的值无效。没有一个选项与{"id":1,"name":"test"}匹配。您可以使用getOptionSelected属性自定义相等测试。
我还意识到,如果我在组件的状态下设置选项,则不会有任何警告(只是当它们被设置为常量时)。所以我想知道你们中的一些人是否对这种行为有任何想法?提前非常感谢。

zdwk9cvp

zdwk9cvp1#

基本上,您收到警告的原因是4.x.x版本中getOptionSelected的默认实现:

getOptionSelected = (option, value) => option === value

在您的情况下,选择一个值会发生以下比较:

// option === value:
{id:1, name:"test"} === {id:1, name:"test"} // false

显然,在某些情况下它可以是true,在这个特定的例子中,它是false,因为对象指向不同的示例。

**解决方案!**需要覆盖getOptionSelected实现:

<Autocomplete
 getOptionSelected={(option, value) => option.id === value.id}
 ...otherProps
/>

**[更新]**注意,在版本5.x.x中, prop 被重命名为:

-  getOptionSelected={(option, value) => option.id === value.id}
+  isOptionEqualToValue={(option, value) => option.id === value.id}
dba5bblo

dba5bblo2#

版本5.0

isOptionEqualToValue={(option, value) => option.value === value.value}
2vuwiymt

2vuwiymt3#

另外,当您希望构建一个搜索器,其中您写入的值不必与选项相同时,您可以将freeSolo设置为true,警告将消失

snvhrwxg

snvhrwxg4#

这是有效的,

getOptionSelected={(option, value) => option.value === value.value}

https://github.com/mui-org/material-ui/issues/18514#issuecomment-606854194

szqfcxe2

szqfcxe25#

关于elVengadors Answer
如果您希望构建一个搜索器,而您在框中键入的值(inputValue)不一定是提供的选项之一,则可以将freeSolo设置为true。

这将停止显示警告消息。

如果您正在创建允许异步查询API的组件,则可能会出现此需求。这将导致options的值根据API的响应而更改,但在更改inputValue以查询API之前已经选择的选项可能不会包含在此新选项列表中。
Autocomplete Component Documentation中,freeSolo被描述为:
如果为true,则自动完成是单独自由的,这意味着用户输入不绑定到提供的选项。

奖金

freeSolo设置为true将删除弹出按钮(自动完成组件右侧的下拉箭头)。要保留此按钮,还应添加forcePopupIcon={true}

nimxete2

nimxete26#

我在添加getOptionSelected错误后遇到了同样的问题。

错误:

<Autocomplete
   fullWidth={true}
   label={'Location'}
   margin={'noraml'}
   multiple={false}
   name={'location'}
   value={formValues.location === '' ? {label: ''} : {label: formValues.location}}
   options={location}
   ref={locationRef}
   onChange={useCallback((e, v) => handleInputChange(e, v))}
/>

**解决方案:**新增getOptionSelected属性

<Autocomplete
   fullWidth={true}
   label={'Location'}
   margin={'noraml'}
   multiple={false}
   name={'location'}
   getOptionSelected={useCallback((option, value) => option.value === value.value)} // added
   value={formValues.location === '' ? {label: ''} : {label: formValues.location}}
   options={location}
   ref={locationRef}
   onChange={useCallback((e, v) => handleInputChange(e, v))}
/>
ztigrdn8

ztigrdn87#

const CustomAutocomplete = ({
  value,
  onChange,
  options,
  name,
  label,
  error,
  inputRef,
  onBlur,
}) => {
  const acValue = useMemo(() => {
    return options.find((option) => option.value === value);
  }, [options, value]);
  return (
    <Autocomplete
      value={acValue}
      disablePortal
      onChange={(e, v) => {
        onChange(v?.value);
      }}
      options={options}
      getOptionLabel={(o) => {
        return o.title;
      }}
      renderInput={(params) => (
        <UnControlledTextField
          {...params}
          fullWidth
          onBlur={onBlur}
          inputRef={inputRef}
          name={name}
          label={label}
          error={error}
        />
      )}
    />
  );
};

在我的例子中,我使用自定义选项,并且只将值存储在表单数据中
我保留选项

{ title, value }

onChange仅存储value部分选项

mum43rcc

mum43rcc8#

我认为你不应该使用<form>来 Package AutoComplete组件。你应该为AutoComplete设置值,并使用一个函数来处理单击按钮提交。
试试这个:

let Form = props => {
  const [value, setValue] = useState({})
  
  const handleOnSubmit = (value) => {
    setValue(value)
    ...
  }

  return(
        <div>
            <Autocomplete
                id="combo-box-demo"
                value={value}
                options={[{id:1,name:"test"},{id:2, name:"test2"}]}
                getOptionLabel={(option) => option.name}
                style={{ width: 300 }}
                renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" />}
            />
            <Button onClick={() => handleOnSubmit(value)}>Submit</Button>
        </div>
  )
}

相关问题