【问题标题】:How do I prevent empty values in my search bar, in React?在 React 中,如何防止搜索栏中出现空值?
【发布时间】:2019-11-18 01:00:29
【问题描述】:

所以,我正在使用 Google Books API 在 React 中构建一个图书查找器。

用户在输入字段中输入他/她要搜索的书名,输入中输入的值会附加到 API url 的末尾。

基本上,每次用户在输入字段中输入内容时都会调用 API,因为我想在搜索栏下方的下拉列表中显示一些结果。问题是,如果用户点击空格键,这是一个空字符串,我会收到一个 HTTP 400 错误,特别是这个:

错误:请求失败,状态码为 400
在 createError (createError.js:17)
定居时 (settle.js:19)
在 XMLHttpRequest.handleLoad (xhr.js:60)

如果我在输入值上调用.trim(),那只会阻止用户输入任何内容。我有点困惑现在该怎么办。此外,每次输入值更改时都调用 API 是一项昂贵的操作吗?这是我迄今为止尝试过的:

import React, { Component } from 'react';
import axios from 'axios';

export default class BookSearchForm extends Component {
  state = {
    searchTerm: ''
  };

  fetchBooks = () => {
    let apiURL = `https://www.googleapis.com/books/v1/volumes`;
    axios
      .get(`${apiURL}?q=${this.state.searchTerm}`)
      .then(res => console.log(res))
      .catch(err => console.log(err));
    };
  
  onChange = e => {
  this.fetchBooks();
  this.setState({ searchTerm: e.target.value });
  };

  render() {
  return (
    <div className="container">
     <form autoComplete="off">
      <input
        className="search-bar"
        type="search"
        placeholder="Search for books"
        onChange={this.onChange}
        value={this.state.searchTerm}
      />
     </form>
    </div>
  );
 }
}

【问题讨论】:

  • 这里有一些想法可以帮助您优化和解决问题。首先,修剪,总是修剪,其次如果修剪后的.length少一个字符,则根本不发送请求。如果修剪后的字符串不包含至少一个字符,则它本质上是'',因此等于没有输入任何内容。最后,只要用户正在输入,就可以消除请求,无需对 API 进行 DDOS

标签: javascript reactjs google-books-api


【解决方案1】:

您可以使用 \s 正则表达式替换空格。 您可能还想在状态更新后获取(setState 的回调):

  onChange = e => {
    this.setState(
      { searchTerm: e.target.value.replace(/\s/g, '') },
      () => {
        this.fetchBooks();
      }
    );
  };

.replace(/\s/g, '') 会将字符串中的所有空格(包括制表符、换行符等)替换为空字符 (''),从而使用户输入中的空格不执行任何操作。

【讨论】:

    【解决方案2】:

    您可以验证用户输入并且不允许空字符串。

    另外,每次输入值更改时调用 API 是一项昂贵的操作吗?

    可能是的。你可能想debounce or throttle your requests

    【讨论】:

      【解决方案3】:

      你可以试试下面的代码。

      onChange = e => {
          let value = e.target.value;
          this.fetchBooks(value.trim());
          this.setState({ searchTerm: e.target.value });
      };
      
      fetchBooks = (str) => {
          if (str) {
              let apiURL = `https://www.googleapis.com/books/v1/volumes`;
              axios
                  .get(`${apiURL}?q=${str}`)
                  .then(res => console.log(res))
                  .catch(err => console.log(err));
          }
      };
      

      是的,每次输入更改都调用 API 成本很高。你应该使用去抖动。

      【讨论】:

        【解决方案4】:

        我认为代码应该是:

         onChange = async (e) => {
           await this.setState({ searchTerm: e.target.value });
           this.fetchBooks();   
          };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-29
          • 2012-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-16
          相关资源
          最近更新 更多