【问题标题】:React.js Autocomplete from scratchReact.js 从头开始​​自动完成
【发布时间】:2019-04-12 22:54:29
【问题描述】:

作为技术测试的一部分,我被要求在 React 中编写一个自动完成输入。我已经完成了这项工作,但我现在想添加使用箭头键在渲染列表上上下导航的功能。我做了一些广泛的谷歌搜索,除了 npm 包之外没有发现任何特定于 React 的内容。

明确地说,我正在寻找类似的东西,但对于 React:https://www.w3schools.com/howto/howto_js_autocomplete.asp

我基本上只需要箭头按钮功能,其他一切正常。

干杯

这是我尝试但无法正常工作的示例。

export default class Example extends Component {
  constructor(props) {
    super(props)
    this.handleKeyDown = this.handleKeyDown.bind(this)
    this.state = {
      cursor: 0,
      result: []
    }
  }

handleKeyDown(e) {
    const { cursor, result } = this.state
    // arrow up/down button should select next/previous list element
    if (e.keyCode === 38 && cursor > 0) {
      this.setState( prevState => ({
        cursor: prevState.cursor - 1
      }))
    } else if (e.keyCode === 40 && cursor < result.length - 1) {
      this.setState( prevState => ({
        cursor: prevState.cursor + 1
      }))
    }
  }

  render() {
    const { cursor } = this.state

    return (
      <Container>
        <Input onKeyDown={ this.handleKeyDown }/>
        <List>
          {
            result.map((item, i) => (
              <List.Item
                key={ item._id }
                className={cursor === i ? 'active' : null}
              >
                <span>{ item.title }</span>
              </List.Item>
            ))
          }
        </List>
      </Container>
    )
  }
}

这是我的代码:

class Search extends Component {
  constructor(props) {
    super(props);
    this.state = {
      location: '',
      searchName: '',
      showSearch: false,
      cursor: 0
    };
  }

handleKeyPress = e => {
    const { cursor, searchName } = this.state;
    // arrow up/down button should select next/previous list element
    if (e.keyCode === 38 && cursor > 0) {
      this.setState(prevState => ({
        cursor: prevState.cursor - 1
      }));
    } else if (e.keyCode === 40 && cursor < searchName.length - 1) {
      this.setState(prevState => ({
        cursor: prevState.cursor + 1
      }));
    }
  };

 render() {
    const { searchName, location } = this.state;

    return (
      <div className="Search">
        <h1>Where are you going?</h1>
        <form id="search-form" onSubmit={this.handleSubmit}>
          <label htmlFor="location">Pick-up Location</label>
          <input
            type="text"
            id="location"
            value={location}
            placeholder="city, airport, station, region, district..."
            onChange={this.handleChange}
            onKeyUp={this.handleKeyUp}
            onKeyDown={this.handleKeyPress}
          />

          {this.state.showSearch ? (
            <Suggestions searchName={searchName} />
          ) : null}

          <button value="submit" type="submit" id="search-button">
            Search
          </button>
        </form>
      </div>
    );
  }

从 RESTful API 呈现列表的代码:

.then(res =>
  this.setState({
    searchName: res.data.results.docs.map(array => (
      <a href="#">
        <div
          key={array.ufi}
          className="locations"
        >
          {array.name}
        </div>
      </a>
    ))
  })
);

【问题讨论】:

  • 您是否尝试过实现您想要的箭头功能?请发布您尝试过的代码
  • 我已经尝试了一些我在这里找到的东西,但没有奏效。我现在将发布我的代码。
  • 创建函数handleKeyDownhandleKeyDown = (e) =&gt; ...,或使用onKeyDown={this.handleKeyDown.bind(this)} 为函数获取正确的this 上下文
  • 试过了,但还是不能让它循环。

标签: javascript reactjs autocomplete


【解决方案1】:

由于您将函数定义为handleKeyDown(e) {...},因此上下文this 未指向类实例的上下文,因此上下文将由 onKeyDown 提供(我想它是window 作为this

所以,你有两种方法:

  1. 将你的函数声明为handleKeyDown = (e) =&gt; {...}

  2. 将handleKeyDown 上下文绑定到组件实例,如onKeyDown={this.handleKeyDown.bind(this)}

另外,不要忘记您可能需要一个 mod items.length 计数器,这意味着当您按下并且已经选择了最后一项时,它将转到第一项。

您将降价存储到状态中的 api 使用只是一件可怕的事情。您不再有权访问这些字符串,而是将其保存为普通数组。将它传递到您需要的地方,并使用它在那里创建 jsx。

此外,您根本不使用您所在州的光标。

【讨论】:

  • 声明了一个事件处理程序并且光标计数正确,但它没有突出显示选项。我怀疑这是因为我没有将值分配给返回的列表。
  • @DanielCross 我不知道 List.Item 的实现,它需要 className 属性吗?
  • 我的列表在 keyPressUp 上呈现,并向 RESTful API 发出 get 请求。这是代码:我已经更改了类名并尝试了该选项,但它仍然无法正常工作。
  • @DanielCross 是的,不要那样做,而是按原样保存数组,并在需要的地方将其转换为 jsx(它似乎是 Suggestions 组件)
  • 有道理。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 1970-01-01
相关资源
最近更新 更多