以编程方式在 material-ui 自动完成文本字段中设置值

Programmatically set value in material-ui Autocomplete TextField

在我的 React 应用程序中,我有一个可以从下拉列表中获取值的输入。对于这个假设,我使用 material-ui 自动完成和 TextField 组件。

问题:如何通过单击按钮而不从下​​拉列表中进行选择以编程方式设置输入值?例如,我想从示例中设置 "The Godfather",这个值应该在输入中直观地看到。

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 }
];

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

导入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

      />
    )}
  />

如果您在这里尝试测试从 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

如果您想在输入中显示默认选择值,您还必须设置自动完成组件的 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"
      />
    )}
  />