如何在React中构建自动完成组件

来自菜鸟教程
跳转至:导航、​搜索

介绍

自动完成功能是一种输入字段根据用户输入建议单词的功能。 这有助于改善应用程序中的用户体验,例如需要搜索的情况。

在本文中,您将研究如何在 React 中构建自动完成组件。 您将使用固定的建议列表、事件绑定、理解键盘代码和操作状态管理。

先决条件

要完成本教程,您将需要以下内容:

  • 需要了解 React。 要了解有关 React 的更多信息,请查看 How To Code in React 系列。

第 1 步 — 构建您的 Autocomplete 组件

Autocomplete 组件是您在自动完成功能中制作功能的地方。

创建一个 Autocomplete.js 文件,并导入 React 并实例化一个 Autocomplete 类:

自动完成.js

import React, { Component, Fragment } from "react";
import './styles.css'

class Autocomplete extends Component {
  constructor(props) {
    super(props);
    this.state = {
      activeSuggestion: 0,
      filteredSuggestions: [],
      showSuggestions: false,
      userInput: ""
    };
  }

在您的状态下,activeSuggestion 属性定义了所选建议的索引。 设置为空数组的属性 filteredSuggestions 匹配用户的输入。 showSuggestions 属性将确定是否出现建议列表,userInput 属性为自己分配一个空字符串,用于接受来自用户输入的单词。

启动类并设置状态后,让我们看看要在组件中应用的方法。

在您的 Autocomplete.js 文件中,定义一个 onChange 方法并更新您的状态:

自动完成.js

  onChange = e => {
    const { suggestions } = this.props;
    const userInput = e.currentTarget.value;

    const filteredSuggestions = suggestions.filter(
      suggestion =>
        suggestion.toLowerCase().indexOf(userInput.toLowerCase()) > -1
    );

    this.setState({
      activeSuggestion: 0,
      filteredSuggestions,
      showSuggestions: true,
      userInput: e.currentTarget.value
    });
  };

当用户更改输入值时,方法 onChange 将触发。 在每次更改时,该方法将过滤到建议列表并返回不包含用户输入的建议。 一旦过滤器运行通过,.setState() 方法将修改您的状态的 userInput 属性以包含一个值,设置您的 showSuggestions 布尔值以允许显示建议,并重置 [X186X ] 属性在每个方法调用。

当用户单击建议时,将调用 onClick 事件。 在您的 Autocomplete.js 文件中,声明一个 onClick 方法并实现一个 .setState() 方法:

自动完成.js

  onClick = e => {
    this.setState({
      activeSuggestion: 0,
      filteredSuggestions: [],
      showSuggestions: false,
      userInput: e.currentTarget.innerText
    });
  };

.setState() 方法将更新用户的输入并重置您的状态属性。

当用户按下一个键时,onKeyDown 方法将启动。 在您的 Autocomplete.js 文件中,声明一个 onKeyDown 方法并设置几个条件:

自动完成.js

  onKeyDown = e => {
    const { activeSuggestion, filteredSuggestions } = this.state;

    if (e.keyCode === 13) {
      this.setState({
        activeSuggestion: 0,
        showSuggestions: false,
        userInput: filteredSuggestions[activeSuggestion]
      });
    } else if (e.keyCode === 38) {
      if (activeSuggestion === 0) {
        return;
      }
      this.setState({ activeSuggestion: activeSuggestion - 1 });
    }
    // User pressed the down arrow, increment the index
    else if (e.keyCode === 40) {
      if (activeSuggestion - 1 === filteredSuggestions.length) {
        return;
      }
      this.setState({ activeSuggestion: activeSuggestion + 1 });
    }
  };

在解构对象中存储属性 activeSuggestionfilteredSuggestion 后,条件将检查用户按下的键是否与键码匹配。 第一个条件将检查键码是否与回车键 13 匹配,然后运行 .setState() 方法更新 userInput 属性并关闭建议列表。 如果用户按下向上箭头,键码 38,条件将递减 activeSuggestion 属性的索引,如果索引为零,则不返回任何内容。 如果用户按下向下箭头,键码 40,条件将增加 activeSuggestion 属性中的索引,如果索引与 filteredSuggestions 的长度匹配,则不返回任何内容] 财产。

现在您的方法已完成,让我们导航到应用您的 render 生命周期方法。

在您的 Autocomplete.js 文件中,设置 render() 语句,并在解构对象中定义您的方法和状态:

自动完成.js

  render() {
    const {
      onChange,
      onClick,
      onKeyDown,
      state: {
        activeSuggestion,
        filteredSuggestions,
        showSuggestions,
        userInput
      }
    } = this;

    let suggestionsListComponent;

变量 suggestionsListComponent 没有定义的值,因为您将在下面的条件中分配它们:

自动完成.js

    if (showSuggestions && userInput) {
      if (filteredSuggestions.length) {
        suggestionsListComponent = (
          <ul class="suggestions">
            {filteredSuggestions.map((suggestion, index) => {
              let className;

              // Flag the active suggestion with a class
              if (index === activeSuggestion) {
                className = "suggestion-active";
              }
              return (
                <li className={className} key={suggestion} onClick={onClick}>
                  {suggestion}
                </li>
              );
            })}
          </ul>
        );
      } else {
        suggestionsListComponent = (
          <div class="no-suggestions">
            <em>No suggestions available.</em>
          </div>
        );
      }
    }

第一个条件将检查属性 showSuggestionsuserInput 上的值是否存在,而以下条件将检查 filteredSuggestions 属性的长度。 如果满足条件,则 suggestionsListComponent 变量为自己分配遍历 filteredSuggestions 属性的值,如果索引与 [ 中的值匹配,则使用类名标记活动建议X211X] 属性。 suggestionsListComponent 变量将在执行 onClick 方法时返回建议的有序列表,并为每个建议分配一个类名。 如果属性 showSuggestionsuserInput 上的值不存在,则会出现一个文本,指示没有可用的建议。

如果用户不满足列出的条件,则 render() 生命周期方法将返回一个 React Fragment 以应用输入字段并调用方法,而无需向文档对象模型添加额外的节点:

自动完成.js

    return (
      <Fragment>
        <input
          type="text"
          onChange={onChange}
          onKeyDown={onKeyDown}
          value={userInput}
        />
        {suggestionsListComponent}
      </Fragment>
    );
  }
}

export default Autocomplete;

现在您已经开发了 Autocomplete 组件,导出文件将其功能合并到另一个组件中。

第二步——加入你的 React 项目

App 组件用于显示 Autocomplete 组件中的功能。 在您的 index.js 文件中,声明一个 App 组件并导入您的 Autocomplete 组件:

index.js

import React from "react";
import Autocomplete from "./Autocomplete";

function App() {
  return (
    <div>
      <h1>React Autocomplete Demo</h1>
      <h2>Start typing and experience the autocomplete wizardry!</h2>
      <Autocomplete suggestions={"Oranges", "Apples", "Banana", "Kiwi", "Mango"]}/>
    </div>
  );
}

export default App

App 组件中的 return 语句接受具有固定建议列表的 Autocomplete 组件。

第 3 步 — 设置 Autocomplete 组件的样式

要完成您的 Autocomplete 组件,请使用 CSS 添加样式以定位和着色您的应用程序和输入字段。

创建一个 styles.css 文件并设置 CSS 规则来塑造您的 Autocomplete 组件:

样式.css

body {
  font-family: sans-serif;
}

input {
  border: 1px solid #999;
  padding: 0.5rem;
  width: 300px;
}

.no-suggestions {
  color: #999;
  padding: 0.5rem;
}

.suggestions {
  border: 1px solid #999;
  border-top-width: 0;
  list-style: none;
  margin-top: 0;
  max-height: 143px;
  overflow-y: auto;
  padding-left: 0;
  width: calc(300px + 1rem);
}

.suggestions li {
  padding: 0.5rem;
}

.suggestion-active,
.suggestions li:hover {
  background-color: #008f68;
  color: #fae042;
  cursor: pointer;
  font-weight: 700;
}

.suggestions li:not(:last-of-type) {
  border-bottom: 1px solid #999;
}

构建完 CSS 规则后,将文件导入 Autocomplete.js 文件以应用样式。

结论

React 提供了一些措施来构建一个组件中可用的自动完成功能,并使用内置和自定义方法与用户交互。

查看自动完成组件在 CodeSandbox 中的运行方式。