Reactjs Search after onChange



我已经在我的reactjs应用程序中实现了一些搜索功能。问题是,我的"搜索处理程序"函数是在用户在文本字段中输入的每个字母后触发的......因此,例如,对于术语"Lorem",我的函数从我的 api :(中获取 5 次

如何解决这个问题?

这是我的代码:

const { scaleDown } = transitions;
function searchingFor(term){
return function(x){
return x.title.toLowerCase().includes(term.toLowerCase()) ||
x.body.toLowerCase().includes(term.toLowerCase());
}
 }  

class ViewAll extends React.Component{
constructor(props){
  super(props);
  this.state = {
    term: '',
    mounted: true,
    tracks: [],
    hasMoreItems: true,
    page: 2,
  }
  this.searchHandler = this.searchHandler.bind(this);
  this.focus = this.focus.bind(this);
  this.keyPress = this.keyPress.bind(this);

 }
  loadContent() {
    var requestUrl = this.props.url;
    fetch(requestUrl + this.state.page + '&_limit=3').then((response)=>{
        return response.json();
    }) .then((tracks)=>{
        this.setState({ tracks: this.state.tracks.concat(tracks)});
        this.setState({page: this.state.page + 1});
        if(this.state.page === 6){
         this.setState({hasMoreItems: false})
       }
    }).catch((err)=>{
        console.log("There has been an error");
    });
}
componentDidMount() {
  window.scrollTo(0, 0);
var requestUrl = this.props.url;
fetch(requestUrl + '1&_limit=3')
    .then((response)=>{
    return response.json();
}) .then((data)=>{
    this.setState({tracks : data});
})
.catch((err)=>{
    console.log("There has been an error");
});
//this.focus();
 }
  searchHandler(event){
    this.setState({term: event.target.value});
    var requestUrl = 'https://questdb.herokuapp.com/all?q='
    fetch(requestUrl + this.state.term).then((response)=>{
        return response.json();
    }) .then((tracks)=>{
        this.setState({ tracks: this.state.tracks.concat(tracks)});

    }).catch((err)=>{
        console.log("There has been an error");
    });
  }
   focus() {
   this.textInput.focus();
 }

    keyPress(e){
       if(e.keyCode == 13){
          console.log('value', e.target.value);
          // put the login here
       }
    }    

render() {   

  const {term, data, tracks} = this.state;
  const loader = <div className="loader2"> </div>;
  var items = [];
  const imageUrl = require(`../assets/Book.jpg`)
  tracks.filter(searchingFor(term)).map(function(title, i)
{
    items.push(
            <div>
              <MuiThemeProvider>
                <Paper style={{ borderRadius: "2em",
                  background: '#ffffff'
                }} zDepth={1} >
          <ItemViewAll
            key={title.id}
              />
      </Paper>
      </MuiThemeProvider>
      </div>
    );
  }, this);

    return (
      <div>    
            <Fade in={true}  timeout={1000}>
<div >
  <MuiThemeProvider>
    <TextField hintText='Bot suchen...'
         type="Text"
         onChange={this.searchHandler}
         value={term}
         underlineFocusStyle={{borderColor: '#B00020', borderWidth: 3}}
         underlineStyle={{borderColor: '#B00020', borderWidth: 1.5, top: '45px'}}
         hintStyle={{fontSize: '8.1vw', fontFamily: 'Anton', color: 'rgba(255,255,255,0.9)'}}
         inputStyle={{fontSize: '8.1vw', fontFamily: 'Anton', color: '#ffffff'}}
         ref={(input) => { this.textInput = input; }}
         style={{caretColor: '#ffffff', width: '90%', maginLeft: 'auto', marginRight: 'auto', marginTop: '12%' }}
         InputLabelProps={{ shrink: true }}
         />

     </MuiThemeProvider>
      </div>
      </Fade>   

    <InfiniteScroll
       pageStart={1}
       loadMore={this.loadContent.bind(this)}
       hasMore={this.state.hasMoreItems}
       initialLoad={true}
      >

              {items}
         </InfiniteScroll>    

</div>
    )
  }
}
export default ViewAll;

在这里,您可以查看具有损坏的搜索功能的网站。如您所见,这些项目显示为两倍甚至三倍......清空文本字段后,应删除搜索结果,仅显示正常提取的结果。

https://www.genko.de(在 chrome 中使用移动版本)

谢谢:)

使用 lodash 去抖动。它用于此确切用例

样本:

import React, {Component} from 'react'
import { debounce } from 'lodash'
class TableSearch extends Component {
  //********************************************/
  constructor(props){
    super(props)
    this.state = {
        value: props.value
    }
    this.changeSearch = debounce(this.props.changeSearch, 250)
  }
  //********************************************/
  handleChange = (e) => {
    const val = e.target.value
    this.setState({ value: val }, () => {
      this.changeSearch(val)
    })
  }
  //********************************************/
  render() {
    return (
        <input
            onChange = {this.handleChange}
            value = {this.props.value}
        />
    )
  }
  //********************************************/
}

如果你不需要完整的 lodash 包,你可以自己写:

function debounce(f, ms) {
  let timer = null;
  return function (...args) {
    const onComplete = () => {
      f.apply(this, args);
      timer = null;
    }
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(onComplete, ms);
  };
}

第一个参数 (f) 是你的函数,它不应该比秒参数 (毫秒) - 毫秒的数量)。因此,在您的情况下,您可以通过以下方式编写处理程序:

handleChange = debounce((e) => {
  const val = e.target.value
  this.setState({ value: val }, () => {
    this.changeSearch(val)
  })
}, 1000) // second arg (1000) is your amount of ms

最新更新