只要用户输入,我都不会触发请求。我的代码应限制请求,以便当用户快速键入内容时,它将使用最新输入值而不是许多输入值触发一个请求。
现在,当我输入“ test”时,它会触发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)
有什么想法可以摆脱这种行为吗?
好吧,用lodash很容易_.debounce。 您用它包装方法并传递要等待的毫秒数。 至于输入的最小长度,仅当长度大于2时才调用new方法。
_.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>