只要用户输入内容,在React中使用Lodash防反跳功能就可以防止请求数据 [英] Using Lodash debounce in React to prevent requesting data as long as the user is typing

查看:72
本文介绍了只要用户输入内容,在React中使用Lodash防反跳功能就可以防止请求数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I don't want to fire requests as long as the user is typing. My code should throttle requests so that when the user types quickly, it will fire one request with the latest input value instead of many.

目前,当我输入"test"时,它会触发4个不同的请求:

For now when I'm typing "test" it fires 4 different requests:

  1. "t"
  2. "te"
  3. "tes"
  4. 测试"

因此,我发现lodash _.debounce和_.throttle([ https://lodash. com/docs/4.17.4#debounce] ),但我不太了解如何将其添加到我的代码中.谁能帮我吗?

So I found lodash _.debounce and _.throttle ( [https://lodash.com/docs/4.17.4#debounce] ) but don't really understand how I can inplement it to my code. Can anyone help me?

我的代码:

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,我要添加一些解释:

Thx to Sagiv b.g, I'm adding some explanation:

好,因此用户应该输入两个以上的字母&&我的应用程序也应该等待至少2秒,然后再开始Ajax请求

ok, so the user should type more than 2 letters && also my app should wait minimum 2 seconds before starting ajax request

感谢Sagiv b.g,这是一个很好的解决方案!

Thx to Sagiv b.g, for great solution!

我已经这样更改了代码:

I've changed my code like so:

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

But it has one last bug, that I don't know how to get rid off. When the user wants to change search query and uses backspace to erase search field, my app always fires unexpectedly another API request. Here is an example:

https://youtu.be/uPEt0hHDOAI

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

推荐答案

使用lodash _.debounce可以轻松实现.
您用它包装方法并传递要等待的毫秒数.
至于输入的最小长度,仅当长度大于2时才调用new方法.

Well this is easy with lodash _.debounce.
You wrap your method with it and pass the milliseconds you want to wait.
As for the minimum length of the input, just invoke the new method only if the length is above 2.

这是一个运行中的小例子:

Here is a small running example:

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>

这篇关于只要用户输入内容,在React中使用Lodash防反跳功能就可以防止请求数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆