以编程方式在 material-ui Autocomplete TextField 中设置值

Posted

技术标签:

【中文标题】以编程方式在 material-ui Autocomplete TextField 中设置值【英文标题】:Programmatically set value in material-ui Autocomplete TextField 【发布时间】:2020-05-04 02:14:23 【问题描述】:

在我的 React 应用程序中,我有一个可以从下拉列表中获取值的输入。对于那个 putpose,我使用 material-ui Autocomplete 和 TextField 组件。

问题:如何在不从下拉列表中选择的情况下通过单击按钮以编程方式设置输入值?例如,我想从示例中设置“教父”,并且应该在输入中直观地看到这个值。

Codesandbox example here

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

export default function ComboBox() 
  const handleClick = () => 
    // set value in TextField from dropdown list
  ;

  return (
    <React.Fragment>
      <Autocomplete
        options=top100Films
        getOptionLabel=option => option.title
        style= width: 300 
        renderInput=params => (
          <TextField
            ...params
            label="Combo box"
            variant="outlined"
            fullWidth
          />
        )
      />
      <Button onClick=handleClick>Set value</Button>
    </React.Fragment>
  );


// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
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 
];

【问题讨论】:

【参考方案1】:

您可以在状态中存储所需的值并将其传递给自动完成组件。

导入useState

   import React,  useState  from 'react';

使用useState

   const [val,setVal]=useState()

点击按钮改变值

  const handleClick = () => 
    setVal(top100Films[0]);//you pass any value from the array of top100Films
   // set value in TextField from dropdown list
 ;

并将这个值传递给渲染中的组件

 <Autocomplete
   value=val
    options=top100Films
    getOptionLabel=option => option.title
    style= width: 300 
    renderInput=params => (
      <TextField
        ...params
        label="Combo box"
        variant="outlined"
        fullWidth

      />
    )
  />

【讨论】:

如果您的自动完成可以有多个值(设置了属性multiple),那么value 属性的值应该是一个数组。对于上述情况,它将是 setVal([top100Films[0]]); 而不是 setVal(top100Films[0]); 传递一个数组不会渲染任何东西。 我在使用 mui 自动完成和 formik 时这样做了。当我在自动完成上设置默认值时,formik 状态不会更新以将默认选定值带入其状态。关于如何做到这一点的任何想法【参考方案2】:

如果您在这里尝试测试从 MUI 的 Autocomplete 组件调用的更改处理程序:

在您的 setupTests.js 文件中

import '@testing-library/jest-dom/extend-expect'

document.createRange = () => (
  setStart: () => ,
  setEnd: () => ,
  commonAncestorContainer: 
    nodeName: 'BODY',
    ownerDocument: document
  
)

在您的测试文件中:

import  render, fireEvent  from '@testing-library/react'

...

const  getByRole  = render(<MyComponentWithAutocomplete />)

const autocomplete = getByRole('textbox')

// click into the component
autocomplete.focus()

// type "a"
fireEvent.change(document.activeElement,  target:  value: 'a'  )

// arrow down to first option
fireEvent.keyDown(document.activeElement,  key: 'ArrowDown' )

// select element
fireEvent.keyDown(document.activeElement,  key: 'Enter' )

expect(autocomplete.value).toEqual('Arkansas')
expect(someChangeHandler).toHaveBeenCalledTimes(1)

更多示例,请查看tests in the library

【讨论】:

【参考方案3】:

如果要在输入中显示默认选择值,还必须设置自动完成组件的 inputValue 属性和 onInputChange 事件

状态变化:

const [value, setValue] = useState("");
const [inputValue, setInputValue] = useState("");

句柄点击的变化

const handleClick = () => 
   setValue(top100Films[0]);
   setInputValue(top100Films[0]);
;

自动完成的变化

 <Autocomplete
    ...custom
    value=value
    inputValue=inputValue
    onChange=(event, newValue) => 
      setValue(newValue);
    
    onInputChange=(event, newInputValue) => 
      setInputValue(newInputValue);
    

    options=top100Films
    getOptionLabel=option => option.title
    renderInput=(params) => (
      <TextField
        ...input
        ...params
        variant="outlined"
      />
    )
  />

【讨论】:

请注意,本例中的value 是一个对象数组,而inputValue 应该是一个字符串:material-ui.com/api/autocomplete 因此handleChange 应该使用title 属性设置inputValue ,例如setInputValue(top100Films[0].title

以上是关于以编程方式在 material-ui Autocomplete TextField 中设置值的主要内容,如果未能解决你的问题,请参考以下文章

React.js Material-UI:以编程方式从子组件中隐藏父组件选项卡

如何在material-ui中的MenuItem上设置焦点

使用 React Material-UI 自动对焦 TextField

如何始终在有焦点的 Material-UI Button 组件上应用 focusVisible 样式?

Material-ui中网格项目的对齐方式

如何在 Material-UI 中使用 Box 组件覆盖按钮?