在onChange之后进行Reactjs搜索

时间:2019-01-03 17:30:33

标签: reactjs search fetch

我在我的reactjs应用程序中实现了一些搜索功能。 问题是,我的“ searchHandler”函数是在用户在文本字段中输入每个字母后触发的。对于术语“ 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中使用移动版本)

谢谢:)

2 个答案:

答案 0 :(得分:2)

使用lodash防抖。用于此确切的用例

$matches

示例:

https://stackoverflow.com/questions/48046061/using-lodash-debounce-in-react-to-prevent-requesting-data-as-long-as-the-user-is

答案 1 :(得分:1)

如果不需要完整的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);
  };
}

第一个arg(f)是您的函数,不应比执行更多次 第二个arg(ms)-ms的数量)。因此,在您的情况下,您可以通过以下方式编写处理程序:

handleChange = debounce((e) => {
  const val = e.target.value

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