javascript - How do I prevent empty values in my search bar, in React? - Stack Overflow

So, I am building a book finder in React using Google Books API.The user types the name of the book he

So, I am building a book finder in React using Google Books API.

The user types the name of the book he/she wants to search, in the input field, and the value typed in the input is appended to the end of the API url.

Basically, the API is called every single time the user types something in the input field, because I want display some of the results in a dropdown below the search bar. The problem is that, if the user hits spacebar, which is an empty string, I get a HTTP 400 error, specifically this:

Error: Request failed with status code 400
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:60)

If I call .trim() on the input value, then that just prevents a user from typing anything at all. I'm kind of confused what to do right now. Also, is calling the API everytime the input value changes an expensive operation? This is what I've tried so far:

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

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

  fetchBooks = () => {
    let apiURL = ``;
    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>
  );
 }
}

So, I am building a book finder in React using Google Books API.

The user types the name of the book he/she wants to search, in the input field, and the value typed in the input is appended to the end of the API url.

Basically, the API is called every single time the user types something in the input field, because I want display some of the results in a dropdown below the search bar. The problem is that, if the user hits spacebar, which is an empty string, I get a HTTP 400 error, specifically this:

Error: Request failed with status code 400
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:60)

If I call .trim() on the input value, then that just prevents a user from typing anything at all. I'm kind of confused what to do right now. Also, is calling the API everytime the input value changes an expensive operation? This is what I've tried so far:

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

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

  fetchBooks = () => {
    let apiURL = `https://www.googleapis./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>
  );
 }
}
Share Improve this question edited Jul 3, 2020 at 0:57 0Valt 10.4k9 gold badges40 silver badges64 bronze badges asked Jul 8, 2019 at 13:38 Vishwanath BVishwanath B 892 silver badges11 bronze badges 2
  • Maybe use this: stackoverflow./questions/26017364/… – Roknix Commented Jul 8, 2019 at 13:42
  • here is a few ideas that might help you both optimize and solve the issue. First of, trim, always trim, secondly if the .length after trim is less a single character, do not send the request at all. If a trimmed string doesn't contain at least one character it is essentially '' and thus equal to not having typed anything. Lastly, debounce the requests so long as the user is typing, no need to DDOS the API – Dellirium Commented Jul 8, 2019 at 13:45
Add a ment  | 

4 Answers 4

Reset to default 2

You can replace whitespaces using the \s regex. You may also want to fetch after the state is updated (callback of setState) :

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

.replace(/\s/g, '') will replace all whitespaces (including tab, newline etc...) from the string by an empty char (''), making whitespaces from user inputs doing nothing.

You could validate the user input and don't allow empty strings.

Also, is calling the API everytime the input value changes an expensive operation?

Likely yes. You might want to debounce or throttle your requests

You can try below code.

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./books/v1/volumes`;
        axios
            .get(`${apiURL}?q=${str}`)
            .then(res => console.log(res))
            .catch(err => console.log(err));
    }
};

Yes, calling API on every input change is expensive. You should use debouncing.

I think the code should be:

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745672888a4639514.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信