只要用户输入

时间:2017-12-31 22:31:47

标签: javascript reactjs react-native lodash

只要用户输入,我就不想发出请求。我的代码应该限制请求,以便当用户快速键入时,它将使用最新的输入值而不是许多输出一个请求。

现在,当我打字"测试"它会激发4个不同的请求:

  1. " T"
  2. " TE"
  3. " TES"
  4. "测试"
  5. 所以我找到了lodash _.debounce和_.throunce([https://lodash.com/docs/4.17.4#debounce]),但我真的不明白如何将它添加到我的代码中。任何人都可以帮助我吗?

    我的代码:

    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    import { bindActionCreators } from 'redux';
    import './style.css';
    
    import { search } from '../../actions/';
    
    class SearchBar extends Component {
      constructor(props) {
        super(props);
        this.state = { searchTerm: '' };
      }
    
      startSearch(query) {
        const storedTerms = this.props.searchedTerm;
        let foundDuplicate = false;
    
        if (storedTerms.length === 0 && query) {
          return this.props.search(query);
        }
    
        if (storedTerms.length !== 0 && query) {
          const testDuplicate = storedTerms.map(term => term === query);
          foundDuplicate = testDuplicate.some(element => element);
        }
    
        if (storedTerms.length !== 0 && !query) {
          return false;
        }
    
        if (foundDuplicate) {
          return false;
        }
    
      return this.props.search(query);
    }
    
    handleInputChange(term) {
      this.setState({ searchTerm: term });
      this.startSearch(term);
    }
    
    render() {
      return (
        <div className="Search-bar">
          <input
            value={this.state.searchTerm}
            onChange={event => this.handleInputChange(event.target.value)}
          />
        </div>
      );
    }
    
    
    function mapStateToProps(state) {
      return {
        searchedTerm: state.searchedTerm,
        savedData: state.savedData,
      };
    }
    
    function mapDispatchToProps(dispatch) {
      return bindActionCreators({ search }, dispatch);
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);
    

    编辑:

    请向Sagiv b.g,我添加一些解释:

    好的,所以用户应输入2个以上的字母&amp;&amp;我的应用程序应该在开始ajax请求之前至少等待2秒

    EDIT2: 感谢Sagiv b.g,以获得出色的解决方案!

    我已经改变了我的代码:

    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    import { bindActionCreators } from 'redux';
    import _ from 'lodash';
    import './style.css';
    
    import { search } from '../../actions/';
    
    class SearchBar extends Component {
      constructor(props) {
        super(props);
        this.state = { inputValue: '' };
    
        this.startSearch = _.debounce(this.startSearch, 2000);
      }
    
      startSearch(query) {
        const storedTerms = this.props.searchedTerm;
        let foundDuplicate = false;
    
        if (storedTerms.length === 0 && query) {
          return this.props.search(query);
        }
    
        if (storedTerms.length !== 0 && query) {
          const testDuplicate = storedTerms.map(term => term === query);
          foundDuplicate = testDuplicate.some(element => element);
        }
    
        if (storedTerms.length !== 0 && !query) {
          return false;
        }
    
        if (foundDuplicate) {
          return false;
        }
    
        return this.props.search(query);
      }
    
      onChange = ({ target: { value } }) => {
        this.setState({ inputValue: value });
        if (value.length > 2) {
          this.startSearch(value);
        }
      };
    
      render() {
        return (
          <div className="Search-bar">
            <input
              placeholder="Type something to search GitHub"
              value={this.state.inputValue}
              onChange={this.onChange}
            />
          </div>
        );
      }
    }
    
    function mapStateToProps(state) {
      return {
        searchedTerm: state.searchedTerm,
        savedData: state.savedData,
      };
    }
    
    function mapDispatchToProps(dispatch) {
      return bindActionCreators({ search }, dispatch);
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);
    

    要处理的最后一个错误

    但它有最后一个错误,我不知道如何摆脱它。当用户想要更改搜索查询并使用退格键擦除搜索字段时,我的应用程序总是会意外触发另一个API请求。 这是一个例子:

    https://youtu.be/uPEt0hHDOAI

    我有什么想法可以摆脱这种行为吗?

1 个答案:

答案 0 :(得分:6)

使用lodash _.debounce这很容易 用它包装你的方法并传递你想要等待的毫秒数 至于输入的最小长度,只有当长度大于2时才调用新方法。

这是一个小例子:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: '',
      inputValue: ''
    };

    this.updateMessage = _.debounce(this.updateMessage, 2000);
  }


  onChange = ({ target: { value } }) => {
    this.setState({ inputValue: value });
    if (value.length > 2) {
      this.updateMessage(value);
    }
  }


  updateMessage = message => this.setState({ message });

  render() {
    const { message, inputValue } = this.state;
    return (
      <div>
        <input placeholder="type something..." value={inputValue} onChange={this.onChange} />
        <hr/>
        <div>server call >> wait 2 seconds & min length of 2</div>
        <p>{message}</p>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.compat.js"></script>
<div id="root"></div>