【问题标题】:How to disable the selection of an item when the first letter of the option is pressed in the Select component?在 Select 组件中按下选项的第一个字母时如何禁用对项目的选择?
【发布时间】:2020-02-11 04:43:36
【问题描述】:

我正在使用材质 UI 选择组件,我正在尝试在内部构建一个过滤器以仅显示与用户输入的输入匹配的项目。

我构建了一个我正在开发的最小示例。

function App() {
  const [selectedOption, setSelectedOption] = React.useState("");
  const [filterExpression, setFilterExpression] = React.useState("");

  const onChangeSelection = (
    event: React.ChangeEvent<{ name?: string | undefined; value: unknown }>,
    child: React.ReactNode
  ) => {
    const value = event.target.value.toString();
    setSelectedOption(value);
  };

  const onChangeExpression = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    const value = event.target.value.toString();
    console.log(`value:`, value);
    setFilterExpression(value);
  };

  const stopImmediatePropagation = (e: any) => {
    e.stopPropagation();
    e.preventDefault();
  };

  return (
    <div className="App">
      <Select onChange={onChangeSelection} value={selectedOption}>
        <MenuItem
          dense
          divider
          value={""}
          onClickCapture={stopImmediatePropagation}
        >
          <TextField value={filterExpression} onChange={onChangeExpression} />
        </MenuItem>

        <MenuItem dense key={"One"} value={"One"}>
          One
        </MenuItem>
        <MenuItem dense key={"Two"} value={"Two"}>
          Two
        </MenuItem>
        <MenuItem dense key={"Three"} value={"Three"}>
          Three
        </MenuItem>
      </Select>
    </div>
  );
}

我现在的问题是,默认情况下,选择组件允许用户按任何字母,如果有第一个字母与用户输入匹配的选项,它会选择该选项。

所以,如果我有 3 个选项(OneTwoThree)并且用户键入 O,则选择组件将选择 One 选项,而我的文本字段的值不会改变。但是,如果用户键入F,则文本字段将更新为F

我想禁用此行为,因此,我一直在尝试阻止 onKeyUpCaptureonChangeCaptureonKeyDownCapture 等事件的传播,但我无法避免这种情况。

您有什么建议可以解决吗? 您可以在此处查看功能示例:

【问题讨论】:

    标签: javascript reactjs typescript material-ui


    【解决方案1】:

    文本焦点导航功能在MenuListonKeyDown中实现(我在大约6个月前的implemented it)。在MenuItem 上停止该事件的传播(也可以在TextField 上停止传播)阻止该事件到达MenuList

    import * as React from "react";
    import { render } from "react-dom";
    import TextField from "@material-ui/core/TextField";
    import Select from "@material-ui/core/Select";
    import MenuItem from "@material-ui/core/MenuItem";
    
    import "./styles.css";
    
    function App() {
      const [selectedOption, setSelectedOption] = React.useState("");
      const [filterExpression, setFilterExpression] = React.useState("");
    
      const onChangeSelection = (
        event: React.ChangeEvent<{ name?: string | undefined; value: unknown }>,
        child: React.ReactNode
      ) => {
        const value = event.target.value.toString();
        setSelectedOption(value);
      };
    
      const onChangeExpression = (
        event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
      ) => {
        const value = event.target.value.toString();
        console.log(`value:`, value);
        setFilterExpression(value);
      };
    
      const stopImmediatePropagation = (e: any) => {
        e.stopPropagation();
        e.preventDefault();
      };
    
      return (
        <div className="App">
          <Select onChange={onChangeSelection} value={selectedOption}>
            <MenuItem
              dense
              divider
              value={""}
              onClickCapture={stopImmediatePropagation}
              onKeyDown={e => e.stopPropagation()}
            >
              <TextField value={filterExpression} onChange={onChangeExpression} />
            </MenuItem>
    
            <MenuItem dense key={"One"} value={"One"}>
              One
            </MenuItem>
            <MenuItem dense key={"Two"} value={"Two"}>
              Two
            </MenuItem>
            <MenuItem dense key={"Three"} value={"Three"}>
              Three
            </MenuItem>
          </Select>
        </div>
      );
    }
    
    const rootElement = document.getElementById("root");
    render(<App />, rootElement);
    

    【讨论】:

    • +1 @Ryan 。这个有诀窍!!!在过去的 4 个小时里,我一直被困在这上面。 Material UI 在早期版本中使用起来非常简单。但是现在它变成了一个对企业应用程序没有用的框架,因为每个企业公司都有自己的 UX 人员,他们指定了 Material UI 中不存在的东西。因此,至少对于在企业级构建库而言,材料 ui 并不完美。它只是在需求时比预期消耗更多的时间。
    • 万一其他人犯了这个错误……&lt;TextField&gt; 必须包裹在 &lt;MenuItem&gt; 中才能正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多