只要用户在打字,我就不想发出请求.我的代码应该限制请求,这样当用户快速键入时,它将使用最新的输入值触发一个请求,而不是多个请求.

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

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

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);

编辑:

Thx给Sagiv b.g,我要补充一些解释:

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


EDIT2: Thx to Sagiv b.g, for great solution!

我对代码做了如下更改:

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);

Last Bug to deal with

但它还有最后一个错误,我不知道如何摆脱.当用户想要更改搜索查询并使用backspace删除搜索字段时,我的应用程序总是意外地触发另一个API请求.

https://youtu.be/uPEt0hHDOAI

Any ideas how I can get rid of that behavior?

推荐答案

使用lodash _.debounce很容易

下面是一个小的运行示例:

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-native相关问答推荐

使用FETCH发送BLOB/文件时为空

何时在 React Native 中使用辅助功能 Role='link'?

如何在 react-native 中使用 Animated 制作 svg 动画

如何在StackNavigator 中实现自定义标题图标?

你如何使 react-native react-navigation 标签栏透明

Realm 和 React Native - 实现自动更新的最佳实践?

Test suite无法运行 TypeError:Cannot read property ‘default’ of undefined

Property body[41] of BlockStatement expected node to be of a type ["Statement"] but instead got "AssignmentExpression"

更改默认的 React Native 下拉箭头图标

当我导航到react-native 的新页面时,如何强制卸载组件?

Typescript:onPress 类型

props验证中缺少 React Navigation 'navigation'

React native + redux-persist:如何忽略键(黑名单)?

如何在react-native中设置 FlatList 的刷新指示器?

Rich ReactNative TextInput

是否可以将 Image.getSize 与静态图像文件一起使用?

axios 的网络错误和react-native

通过 IOS 中的 Linking.openURL React Native Open 设置

React Native Build Error on IOS - typedef 用不同类型重新定义('uint8_t'(又名'unsigned char')与'enum clockid_t')

如何从 react-native-fbsdk 获取用户信息(邮箱、姓名等)?