2017-02-14 4 views
5

Мне нужно выполнить поиск, когда пользователь перестает печатать. Я знаю, что должен использовать setTimeout(). Но с Reactjs Я не могу найти, как это работает. Может кто-нибудь скажет мне, как вызвать метод (который будет обрабатывать поиск), когда пользователь перестанет печатать на несколько секунд (предположим 5). Я не могу определить, где писать код, чтобы проверить, что пользователь прекратил печатать.Поиск в ответе, когда пользователь перестает печатать

import React, {Component, PropTypes} from 'react'; 

export default class SearchBox extends Component { 

    state={ 
     name:" ", 
    } 

    changeName = (event) => { 
     this.setState({name: event.target.value}); 
    } 

    sendToParent =() => { 
     this.props.searching(this.state.name); 
    } 

    render() { 
     return (
      <div> 
       <input type="text" placeholder='Enter name you wish to Search.' onChange={this.changeName} /> 

      </div> 
     ); 
    } 
} 

Я хочу вызвать метод sendToParent, когда пользователь перестает печатать.

+0

Ну они набрав в качестве входного элемента? Если это так, элементы ввода имеют атрибут «onKeyPress», который вызывается каждый раз, когда нажимает кнопку, пока этот вход выбран. Таким образом, вы можете использовать его так, чтобы таймаут запускался каждый раз, когда нажимал кнопку, но если они снова нажимают кнопку до истечения таймаута, он сбрасывает таймер. Если они не набрали для X времени, тайм-аут выполняет поиск. – Jayce444

+0

Если вы имеете в виду фактический код, который выполняет проверку тайм-аута и проверку «прекратил печатать», то есть много примеров из них онлайн – Jayce444

+0

. Мой метод не вызывает при использовании onkeyPress – shinite

ответ

8

Вы можете использовать setTimeout относительно вашего кода следующим образом,

state = { 
    name: '', 
    typing: false, 
    typingTimeOut: 0 
} 
changeName = (event) => { 
    const self = this; 

    if (self.state.typingTimeout) { 
     clearTimeout(self.state.typingTimeout); 
    } 

    self.setState({ 
     name: event.target.value, 
     typing: false, 
     typingTimeout: setTimeout(function() { 
      self.sendToParent(self.state.name); 
     }, 5000) 
    }); 
} 

Кроме того, вы должны связать changeName функцию обработчика в конструкторе.

constructor(props) { 
    super(props); 
    this.changeName = this.changeName.bind(this); 
} 
+0

Спасибо, он сработал .. :) – shinite

+1

Я опаздываю на вечеринку, но я хотел бы указать, что вам не нужно связывать функцию changeName при использовании синтаксиса стрелок es6. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – MEnf

+0

По этой же причине вам не нужно устанавливать 'const self = this'. 'this' уже привязан к классу. – MEnf

1

Проблема машинописных библиотек https://twitter.github.io/typeahead.js/

Поскольку в данном случае просто, я могу использовать быстрый и грязный раствор:

onChange: (event) -> 
    if @_timeoutTask? 
    clearTimeout @_timeoutTask 

    @_timeoutTask = setTimeout (=> 
    @sendToParent event.target.value 
    clearTimeout @_timeoutTask 
), 5000 

Таким образом, задача будет запускаться 5s после ввода события. Если произойдет новое событие, старая задача будет отменена, и будет запланирована новая задача, а затем еще 5 секунд.

Разница в реактиве - это то, где хранить состояние вычисления, например _timeoutTask. Область файла, состояние компонента или экземпляр компонента.

С _timeoutTask - уровень компонента, он должен быть в глобальном масштабе. И это не влияет на рендеринг, поэтому не в состоянии компонента тоже. Поэтому я предлагаю напрямую связать его с экземпляром компонента.

0

Вы можете просто использовать debounce от lodash или имитировать с помощью setTimeout.

import React, {Component, PropTypes} from 'react'; 

export default class SearchBox extends Component { 
    constructor(props){ 
     super(props); 
     this.state={ name:" "} 
     this.timeout = null; 

    } 

    changeName = (event) => { 
     clearTimeout(timeout); 
     if(timeout){ 
      setTimeout((event)=> this.setState({name: event.target.value}), 200) 
     } 
    } 

    sendToParent =() => { 
     this.props.searching(this.state.name); 
    } 

    render() { 
     return (
      <div> 
       <input type="text" placeholder='Enter name you wish to Search.' onChange={this.changeName} /> 

      </div> 
     ); 
    } 
} 
2

Другой способ, который работал со мной:

class Search extends Component { 
    constructor(props){ 
    super(props); 
    this.timeout = 0; 
    } 

    doSearch(evt){ 
    var searchText = evt.target.value; // this is the search text 
    if(this.timeout) clearTimeout(this.timeout); 
    this.timeout = setTimeout(() => { 
     //search function 
    }, 300); 
    } 

    render() { 
    return (
     <div className="form-group has-feedback"> 
     <label className="control-label">Any text</label> 
     <input ref="searchInput" type="text" onChange={evt => this.doSearch(evt)} /> 
     </div> 
    ); 
    } 
}