Reactjs 在文本字段中键入时显示关联菜单

Reactjs 在文本字段中键入时显示关联菜单,reactjs,material-ui,Reactjs,Material Ui,我正在尝试实现一个上下文菜单,当用户使用。其思想是根据文本字段中当前键入的单词在上下文菜单中显示建议。因此,上下文菜单显示在插入符号输入旁边,不应干扰用户继续键入 但问题是,当显示菜单时,焦点从文本字段中取出,用户无法继续键入,直到菜单关闭 是否有一种方法可以允许显示菜单,同时仍将焦点放在文本字段上,从而允许用户继续键入 <Menu keepMounted open={contextMenuOpen} onClose={handleClose

我正在尝试实现一个上下文菜单,当用户使用。其思想是根据文本字段中当前键入的单词在上下文菜单中显示建议。因此,上下文菜单显示在插入符号输入旁边,不应干扰用户继续键入

但问题是,当显示菜单时,焦点从文本字段中取出,用户无法继续键入,直到菜单关闭

是否有一种方法可以允许显示菜单,同时仍将焦点放在文本字段上,从而允许用户继续键入

<Menu
        keepMounted
        open={contextMenuOpen}
        onClose={handleClose}
        anchorReference="anchorPosition"
        anchorPosition={     
             { top: caretPositionY, left: caretPositionX}           
        }
      >
        <MenuItem onClick={handleClose}>Suggestion1</MenuItem>
        <MenuItem onClick={handleClose}>Suggestion2</MenuItem>
        <MenuItem onClick={handleClose}>Suggestion3</MenuItem>
        <MenuItem onClick={handleClose}>Suggestion4</MenuItem>
      </Menu>

建议1
建议2
建议3
建议4

如果您无法使用材质UI
菜单
,以下是备选方案:-

  • Demo.js
    (使用简单的
    ul
    元素和包
    类名
    ):-
import React,{useState,useffect}来自“React”;
从“类名”中导入类名;
从“@material ui/core/styles”导入{makeStyles}”;
从“@material ui/core”导入{Button,TextField}”;
导入“/style.css”;
常量演示=()=>{
const classes=useStyles();
const[search,setSearch]=useState(“”);
常量[openMenu,setOpenMenu]=使用状态(false);
常量[menuItems,setMenuItems]=useState([
{id:1,名称:“Profile”},
{id:2,名称:“我的帐户”},
{id:3,名称:“注销”}
]);
常量[menuItemsFiltered,setMenuItemsFiltered]=useState(menuItems);
常量handleClose=()=>{
设置菜单(假);
};
const handleSearch=值=>{
如果(值==“”){
设置菜单(假);
setMenuItemsFiltered(menuItems);
}否则{
设置菜单(真);
setMenuItemsFiltered(()=>
menuItems.filter(
item=>item.name.toLowerCase().indexOf(value.toLowerCase())>-1
)
);
}
};
useffect(()=>{
handleSearch(搜索);
},[搜索];
返回(
setSearch(e.target.value)}
/>
setOpenMenu(!openMenu)}
>
打开菜单
    {menuItemsFiltered.map(项=>(
  • handleClose()} > {item.name}
  • ))}
); }; 导出默认演示; const useStyles=makeStyles(主题=>({ 根目录:{ 显示:“flex” }, 菜单:{ listStyle:“无”, 填充:“0.5雷姆”, 背景色:主题。调色板。灰色[100], “&li:不是(:最后一个孩子)”:{ marginBottom:“1rem” } }, 梅努希德:{ 显示:“无” }, 菜单项:{ “&:悬停”:{ 光标:“指针”, 颜色:theme.palete.primary.main } } }));
您可以在沙盒中看到正在运行的演示

import React, { useState, useEffect } from "react";
import classNames from "classnames";
import { makeStyles } from "@material-ui/core/styles";
import { Button, TextField } from "@material-ui/core";
import "./style.css";

const Demo = () => {
  const classes = useStyles();
  const [search, setSearch] = useState("");
  const [openMenu, setOpenMenu] = useState(false);
  const [menuItems, setMenuItems] = useState([
    { id: 1, name: "Profile" },
    { id: 2, name: "My Account" },
    { id: 3, name: "Logout" }
  ]);
  const [menuItemsFiltered, setMenuItemsFiltered] = useState(menuItems);

  const handleClose = () => {
    setOpenMenu(false);
  };

  const handleSearch = value => {
    if (value === "") {
      setOpenMenu(false);
      setMenuItemsFiltered(menuItems);
    } else {
      setOpenMenu(true);
      setMenuItemsFiltered(() =>
        menuItems.filter(
          item => item.name.toLowerCase().indexOf(value.toLowerCase()) > -1
        )
      );
    }
  };

  useEffect(() => {
    handleSearch(search);
  }, [search]);

  return (
    <div className={classes.root}>
      <TextField
        type="search"
        value={search}
        onChange={e => setSearch(e.target.value)}
      />
      <div>
        <Button
          aria-controls="simple-menu"
          aria-haspopup="true"
          onClick={() => setOpenMenu(!openMenu)}
        >
          Open Menu
        </Button>
        <ul
          className={
            openMenu ? classes.menu : classNames(classes.menu, classes.menuHide)
          }
        >
          {menuItemsFiltered.map(item => (
            <li
              key={item.id}
              className={classes.menuItem}
              onClick={() => handleClose()}
            >
              {item.name}
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
};

export default Demo;

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex"
  },
  menu: {
    listStyle: "none",
    padding: "0.5rem",
    backgroundColor: theme.palette.grey[100],
    "& li:not(:last-child)": {
      marginBottom: "1rem"
    }
  },
  menuHide: {
    display: "none"
  },
  menuItem: {
    "&:hover": {
      cursor: "pointer",
      color: theme.palette.primary.main
    }
  }
}));