小编典典

只要用户输入内容,在React中使用Lodash防反跳功能就可以防止请求数据

reactjs

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

现在,当我输入“ test”时,它会触发4个不同的请求:

  1. “ t”
  2. “ te”
  3. “ tes”
  4. “测试”

所以我找到了lodash .debounce和.throttle(
[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);

编辑:

Thx到Sagiv bg,我添加一些解释:

好的,因此用户应该键入2个以上的字母&&另外,我的应用程序应至少等待2秒钟,然后再开始ajax请求


EDIT2:感谢Sagiv bg,这是一个很好的解决方案!

我已经像这样更改了代码:

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请求。这是一个例子:

//youtu.be/uPEt0hHDOAI)

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


阅读 300

收藏
2020-07-22

共1个答案

小编典典

好吧,用lodash很容易_.debounce
您用它包装方法并传递要等待的毫秒数。
至于输入的最小长度,仅当长度大于2时才调用new方法。

这是一个小的运行示例:

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>
2020-07-22