Search code examples
javascriptreactjstypeahead.jsreact-bootstrap-typeahead

React Bootstrap Typeahead specifies the length of characters in the input field


First problem: Why, if I enter one letter in input, console.log (this.state.results.length) does not show me 1. Only after entering two letters console.log (this.state.results.length) shows me 2.

Second problem: I will type three letters, then remove two letters, console.log (this.state.results.length) should show me 1 and show2. The same is when I clear the input it should show 0;

Demo here: https://stackblitz.com/edit/react-frleaq

class App extends Component {
  constructor() {
    super();
    this.state = {
      results: ''
    };
  }

_handleSearch = query => {
  this.setState({
    results: query
  })
}


  render() {
    console.log(this.state.results.length)
    return (
      <div>
         <AsyncTypeahead
            clearButton
            id="basic-example"
            labelKey="name"
            onSearch={this._handleSearch}
          />
      </div>
    );
  }
}

Solution

  • You can use onInputChange to handle text changes and you can keep the text in state. This way you can check it's length and do whatever you want.

    Example:

    import React from "react";
    
    import { AsyncTypeahead } from "react-bootstrap-typeahead";
    import "bootstrap/dist/css/bootstrap.css";
    import "react-bootstrap-typeahead/css/Typeahead.css";
    
    class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          isLoading: false,
          multiple: true,
          options: [],
          selectedUsers: [],
          currentInput: ""
        };
      }
    
      handleSearch = query => {
        this.setState({ isLoading: true });
        fetch(
          `https://api.github.com/search/users?q=${query}+in:login&page=1&per_page=3`
        )
          .then(resp => resp.json())
          .then(({ items }) => {
            const options = items.map(i => ({
              id: i.id,
              name: i.login
            }));
            return { options };
          })
          .then(({ options }) => {
            this.setState({
              isLoading: false,
              options
            });
          });
      };
    
      handleChange = selectedItems => {
        this.setState({
          selectedUsers: selectedItems,
          currentInput: ""
        });
      };
    
      handleInputChange = input => {
        this.setState({
          currentInput: input
        });
      };
    
      render() {
        const { selectedUsers, isLoading, options, currentInput } = this.state;
    
        return (
          <div>
            <AsyncTypeahead
              clearButton
              id="basic-example"
              isLoading={isLoading}
              options={options}
              minLength={3}
              multiple
              labelKey="name"
              onSearch={query => this.handleSearch(query)}
              onChange={selectedItems => this.handleChange(selectedItems)}
              onInputChange={input => this.handleInputChange(input)}
              placeholder="Search for users"
            />
            <hr />
            <br/>
            <br/>
            <br/>
            {currentInput.length > 0 && <button>MY BUTTON</button>}
            <hr />
            Selected {selectedUsers.length} Users: <br />
            <ul>
              {selectedUsers.map(user => (
                <li key={user.id}>{user.name}</li>
              ))}
            </ul>
          </div>
        );
      }
    }
    
    export default App;