首页 > 解决方案 > 如何确定用户是否使用箭头键滚动选择 Material-UI 自动完成?

问题描述

我在 ReactJS 应用程序中有一个 Material UI 自动完成组件,我希望它具有以下行为:

  1. 用户可以在自动完成中输入输入,当用户按下回车键而不滚动浏览建议的选项时,将触发事件 A,并将自动完成中输入的输入作为参数。
  2. 用户可以滚动浏览建议的选项(使用箭头键),当用户按下回车键时,事件 B 会在参数中使用当前选择的自动完成选项触发
  3. 用户可以滚动浏览建议的选项(使用箭头键/鼠标滚动条),当用户单击其中一个建议时,会触发事件 B,并在参数中使用单击的自动完成选项

我能够单独做出这些行为。我使用 onKeyDown 等待输入键处理了第一个行为,并使用了 onChange 处理了第二个 + 第三个行为,如下所示: stackoverflow.com/questions/58666189/getting-the-value-in-the-react-material-ui -自动完成

当我将两个事件放在一起时,问题就出现了。当我尝试使用箭头键滚动选项并按 Enter 键(行为 2)时,onKeyDown 和 onChange 事件都会被触发。当我只想用用户选择的内容触发事件 B 时,这会触发两个事件 A 与用户键入的内容和事件 B 与用户选择的内容。有没有办法检测用户是否已经开始使用箭头键滚动浏览自动完成建议(以便我可以将事件 A 包装在 if 条件中),或者另一种方法来查看这个问题来解决它?

自动完成组件:

<Autocomplete options={someArrayOfStrings}
                            onChange={this.submitComment} // event B
                            onKeyDown={this.submitCommentEnter} // event A
                            value={this.state.userInput} // what the user has typed
                            autoComplete
                            freeSolo
                            renderInput={(params) => <TextField {...params}
                                                                fullWidth
                                                                label="Search"                                                           
                                                                variant="outlined"/>}/>

事件 A (submitCommentEnter):

submitCommentEnter(e) {
        if (e.key == 'Enter') { // possibly add check if user is scrolling through autocomplete with arrow keys here?
            /* content of event A here; uses this.state.userInput */
        }
    }

事件 B(提交评论):

submitComment(event, value) {
        if (value !== null) {
            /* content of event B here; uses value */
        }
    }

标签: reactjsautocompletematerial-uionchangeonkeydown

解决方案


您不需要处理keyDown事件,您只需要on-change根据文档onChange提供三个参数使用事件的原因

 onChange={(event, value, reason) => {
          console.log("onChange", reason, value, event.currentTarget);
 }}

原因可以有5种"create-option", "select-option", "remove-option", "blur" or "clear"。当您在文本字段中按回车时,原因将是create-option,当您从下拉列表中选择一个选项时,原因将是select-options,下面是验证事实的完整代码。

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

const someArrayOfStrings = ["test", "test2", "test3"];

export default function CheckboxesTags() {
  const [selectedValues, setSelectedValues] = React.useState();
  return (
    <React.Fragment>
      <Autocomplete
        options={someArrayOfStrings}
        onChange={(event, value, reason) => {
          console.log("onChange", reason, value, event.currentTarget);
          // setSelectedValues(value);
        }}
        value={selectedValues} // what the user has typed
        autoComplete
        freeSolo
        renderInput={params => (
          <TextField {...params} fullWidth label="Search" variant="outlined" />
        )}
      />
    </React.Fragment>
  );
}

我还创建了这个代码沙盒项目,您可以在其中检查控制台


推荐阅读