如何使用Material-UI Autocomplete组件选择多个选项并添加新选项?

Her*_*ery 12 javascript typescript reactjs material-ui

目标

我有一个多个字段:

  1. 我们可以选择自动完成中存在的用户(我通过 API 检索的列表)
  2. 我们可以输入新用户的名称,并用逗号分隔它们

为此,我需要检索valueinputValue的值。对于value,没有问题,但是对于inputValue,有一些我不明白的东西

问题

当我修改onInputChangeinputValue的值时,它的状态会像这样被修改和重置

信息

我基于Material UI 提供的示例

沙盒中的代码

代码

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

interface User {
  id: number;
  name: string;
}

const userList: User[] = [
  { id: 1, name: "name 1" },
  { id: 2, name: "name 2" },
  { id: 3, name: "name 3" }
];

export default function AutocompleteControlled() {

  const [users, setUsers] = React.useState<number[]>([]);
  const [inputValue, setInputValue] = React.useState("");

  return (
    <div>
      <br />
      <Autocomplete
        multiple
        value={userList.filter((el) => users.includes(el.id))}
        onChange={(event: any, newValue: User[]) => {
          setUsers(newValue.map((el) => el.id));
        }}
        inputValue={inputValue}
        onInputChange={(event: any, newInputValue: string) => {
          console.log("newInputValue", newInputValue);
          setInputValue(newInputValue);
        }}
        id="controllable-states-demo"
        options={userList}
        getOptionLabel={(option) => option.name}
        renderInput={(params) => (
          <TextField {...params} label="Controllable" variant="outlined" />
        )}
      />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

欢迎所有评论:)

Moe*_*Moe 26

您想要启用多项选择,并允许用户在文本框中输入任意值。因此,您可以使用Autocomplete将 prop 设置为 true 的组件freesolo,这样文本框就可以包含任意值。

是最接近您的用例的 Material-UI 示例。

我们将使用受控组件,因此您可以使用valueonChange属性控制其行为。检查下面的代码。

你可以从预先填充的项目中进行选择,也可以输入任意值并按回车键,一个芯片将被添加到组件中,并且该值将被添加到状态中的数组中。

当前value是一个名称数组,但您可以将其设置为ids 或任何您想要的值。

试试这个代码:

import React from "react";
import Chip from "@material-ui/core/Chip";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      width: 500,
      "& > * + *": {
        marginTop: theme.spacing(3),
      },
    },
  })
);

interface User {
  id: number;
  name: string;
}

const userList: User[] = [
  { id: 1, name: "name 1" },
  { id: 2, name: "name 2" },
  { id: 3, name: "name 3" },
  { id: 4, name: "name 4" },
  { id: 5, name: "name 5" },
];

export default function AutocompleteControlled() {
  const classes = useStyles();

  const [value, setValue] = React.useState<any>([userList[0].name]);

  console.log("value: ", value);

  return (
    <div className={classes.root}>
      <Autocomplete
        value={value}
        onChange={(event, newValue) => {
          setValue(newValue);
        }}
        multiple
        id="tags-filled"
        options={userList.map((option) => option.name)}
        freeSolo
        renderTags={(value: string[], getTagProps) =>
          value.map((option: string, index: number) => (
            <Chip
              variant="outlined"
              label={option}
              {...getTagProps({ index })}
            />
          ))
        }
        renderInput={(params) => (
          <TextField
            {...params}
            variant="filled"
            label="Users"
            placeholder="Search"
          />
        )}
      />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

看起来是这样的,受控值被记录到控制台。

截屏