从材料 ui 处理自动完成组件的更改

Posted

技术标签:

【中文标题】从材料 ui 处理自动完成组件的更改【英文标题】:Handle change on Autocomplete Component from material ui 【发布时间】:2020-02-29 05:56:01 【问题描述】:

我想使用Autocomplete 组件作为输入标签。我正在尝试获取标签并将它们保存在一个状态中,以便以后可以将它们保存在数据库中。我在反应中使用函数而不是类。我确实尝试了onChange,但没有得到任何结果。

<div style= width: 500 >
  <Autocomplete
    multiple
    options=autoComplete
    filterSelectedOptions
    getOptionLabel=(option) => option.tags
    renderInput=(params) => (
      <TextField
        className=classes.input
        ...params
        variant="outlined"
        placeholder="Favorites"
        margin="normal"
        fullWidth
      />
    )
  />
</div>;

【问题讨论】:

【参考方案1】:

正如 Yuki 已经提到的,请确保您确实正确使用了 onChange 函数。它接收两个参数。根据文档:

签名function(event: object, value: any) =&gt; void.

event:回调的事件源

value: null(自动完成组件中的值)。

这是一个例子:

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

export default class Tags extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
      tags: []
    ;
    this.onTagsChange = this.onTagsChange.bind(this);
  

  onTagsChange = (event, values) => 
    this.setState(
      tags: values
    , () => 
      // This will output an array of objects
      // given by Autocompelte options property.
      console.log(this.state.tags);
    );
  

  render() 
    return (
      <div style= width: 500 >
        <Autocomplete
          multiple
          options=top100Films
          getOptionLabel=option => option.title
          defaultValue=[top100Films[13]]
          onChange=this.onTagsChange
          renderInput=params => (
            <TextField
              ...params
              variant="standard"
              label="Multiple values"
              placeholder="Favorites"
              margin="normal"
              fullWidth
            />
          )
        />
      </div>
    );
  


const top100Films = [
   title: 'The Shawshank Redemption', year: 1994 ,
   title: 'The Godfather', year: 1972 ,
   title: 'The Godfather: Part II', year: 1974 ,
   title: 'The Dark Knight', year: 2008 ,
   title: '12 Angry Men', year: 1957 ,
   title: "Schindler's List", year: 1993 ,
   title: 'Pulp Fiction', year: 1994 ,
   title: 'The Lord of the Rings: The Return of the King', year: 2003 ,
   title: 'The Good, the Bad and the Ugly', year: 1966 ,
   title: 'Fight Club', year: 1999 ,
   title: 'The Lord of the Rings: The Fellowship of the Ring', year: 2001 ,
   title: 'Star Wars: Episode V - The Empire Strikes Back', year: 1980 ,
   title: 'Forrest Gump', year: 1994 ,
   title: 'Inception', year: 2010 ,
];

【讨论】:

好收获!使用值而不是 event.target.value 解决了问题【参考方案2】:

我需要在每次输入更改时点击我的 api 以从后端获取我的标签!

如果您想在每次输入更改时获得建议的标签,请使用 Material-ui onInputChange!

this.state = 
  // labels are temp, will change every time on auto complete
  labels: [],
  // these are the ones which will be send with content
  selectedTags: [],



//to get the value on every input change
onInputChange(event,value)
console.log(value)
//response from api
.then((res) => 
      this.setState(
        labels: res
      )
    )



//to select input tags
onSelectTag(e, value) 
this.setState(
  selectedTags: value
)



            <Autocomplete
            multiple
            options=top100Films
            getOptionLabel=option => option.title
            onChange=this.onSelectTag // click on the show tags
            onInputChange=this.onInputChange //** on every input change hitting my api**
            filterSelectedOptions
            renderInput=(params) => (
              <TextField
                ...params
                variant="standard"
                label="Multiple values"
                placeholder="Favorites"
                margin="normal"
                fullWidth
              />

【讨论】:

您是如何在下拉列表中显示在 onInputChange 函数的 API 调用中获取的选项的?就我而言,除非我关闭下拉菜单并打开它,否则不会填充选项 @Aditya 我在关闭和重新打开时遇到了同样的问题。我发现解决方案是覆盖默认的 filterOptions。尝试将 filterOptions=(options, state) => options 作为道具添加到您的 组件中。【参考方案3】:

你确定你正确使用了onChange吗?

onChange签名function(event: object, value: any) =&gt; void

【讨论】:

【参考方案4】:

当我从自动完成中选择一个选项时,我想更新我的状态。我有一个管理所有输入的全局 onChange 处理程序

         const name, value  = event.target;
         setTukio(
          ...tukio,
          [name]: value,
        );

根据字段名称动态更新对象。但在自动完成上,名称返回空白。所以我将处理程序从onChange 更改为onSelect。然后创建一个单独的函数来处理更改,或者在我的例子中添加一个 if 语句来检查名称是否未通过。

// This one will set state for my onSelect handler of the autocomplete 
     if (!name) 
      setTukio(
        ...tukio,
        tags: value,
      );
      else 
      setTukio(
        ...tukio,
        [name]: value,
      );
    

如果你有一个自动完成,上述方法有效。如果你有多个你可以传递一个自定义函数,如下所示

<Autocomplete
    options=tags
    getOptionLabel=option => option.tagName
    id="tags"
    name="tags"
    autoComplete
    includeInputInList
    onSelect=(event) => handleTag(event, 'tags')
          renderInput=(params) => <TextField ...params hint="koo, ndama nyonya" label="Tags" margin="normal" />
        />

// The handler 
const handleTag = ( target , fieldName) => 
    const  value  = target;
    switch (fieldName) 
      case 'tags':
        console.log('Value ',  value)
        // Do your stuff here
        break;
      default:
    
  ;

【讨论】:

【参考方案5】:

@Dworo

适用于在输入字段的下拉菜单中显示所选项目时遇到问题的任何人。

我找到了解决方法。基本上,您必须为AutocompleteTextFieldonChage 绑定一个inputValue

const [input, setInput] = useState('');

<Autocomplete
  options=suggestions
  getOptionLabel=(option) => option
  inputValue=input
  onChange=(e,v) => setInput(v)
  style= width: 300 
  renderInput=(params) => (
    <TextField ...params label="Combo box" onChange=( target ) => setInput(target.value) variant="outlined" fullWidth />
  )
/>

【讨论】:

以上是关于从材料 ui 处理自动完成组件的更改的主要内容,如果未能解决你的问题,请参考以下文章

移除 React Material ui 组件中自动完成的下划线样式

如何更改 Material ui 自动完成中选项的字体大小?

如何在反应材料-ui自动完成中实现最小字符长度功能

如何将 onchange 与自动完成材料 ui 一起使用?

React js材料ui自动完成芯片,里面有一个按钮

反应材料 ui 自动完成元素焦点 onclick