【问题标题】:Material-ui Autocomplete warning The value provided to Autocomplete is invalidMaterial-ui Autocomplete 警告 提供给 Autocomplete 的值无效
【发布时间】:2020-09-08 21:01:47
【问题描述】:

我正在使用 React 和 material-ui.. 我只是意识到当我尝试提交表单时,自动完成组件有一个警告,所以我尝试做一些非常基本的事情,就像在文档中一样:

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" />}
            />

当我尝试提交表单时,我收到以下错误:

Material-UI:提供给自动完成的值无效。 没有一个选项与@​​987654322@ 匹配。 您可以使用 getOptionSelected 属性自定义相等测试。

我还意识到,如果我将选项设置为组件的状态,则不会出现警告(仅当它们被设置为常量时)。所以我想知道你们中的一些人是否对这种行为有任何想法?非常感谢您。

【问题讨论】:

    标签: reactjs autocomplete material-ui


    【解决方案1】:

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

     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 版本中,该道具已重命名:

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

    【讨论】:

    • next.material-ui.com/guides/migration-v4 在 MUI 5 版中,getOptionSelected 已重命名为 isOptionEqualToValue
    • 谢谢。但是,如果我的自动完成功能从后端获取选项,并且没有一个新选项与旧值匹配?
    • 我可以返回 true 吗?由于我是从后端获取值,这意味着该值是正确的?
    【解决方案2】:

    这行得通,

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

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

    【讨论】:

      【解决方案3】:

      我认为你不应该使用&lt;form&gt; 来包装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>
        )
      }
                  

      【讨论】:

      • 谢谢你的回答迈克尔。你介意让我知道这样做的原因吗?...因为自动完成属于一个表单,其中包含我需要在那里的许多其他字段..
      • @JulioLopez 根据我的经验,我通常使用这种模式来处理表单。我觉得我对我的组件有更多的控制权。我可以控制将提交哪些数据字段而不依赖于表单。如果您想在提交之前在组件的其他部分中使用这些数据字段之一,会发生什么情况?如果您有许多其他字段,您应该为这些字段设置一个值,就像我对AutoComplete 组件所做的那样。如果您的表单中有超过 3 个字段,您可以使用 useReducer 来存储和操作您的数据字段。
      猜你喜欢
      • 1970-01-01
      • 2021-08-16
      • 2020-08-08
      • 2020-02-28
      • 2020-08-06
      • 2021-02-16
      • 1970-01-01
      • 2020-09-06
      • 2020-07-27
      相关资源
      最近更新 更多