4

У меня есть событие onchange для поля, которое нужно отменить, я использую для этого подчеркивание, однако, когда я использую debouncer, событие, переданное обработчику React, оказывается вне Дата.Использование debouncer с событием React

<div className='input-field'> 
    <input onChange={_.debounce(this.uriChangeHandler.bind(this), 500)} id='source_uri' type='text' name='source_uri' autofocus required /> 
    <label htmlFor='source_uri'>Website Link</label> 
</div> 

uriChangeHandler(event) { 
    event.preventDefault(); 
    let uriField = $(event.target); 
    let uri = uriField.val(); 
    this.setState({ 
     itemCreateError: null, 
     loading: true 
    }); 
    this.loadUriMetaData(uri, uriField); 
} 

Я получаю эту ошибку: Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're calling preventDefault on a released/nullified synthetic event. This is a no-op. See https://fb.me/react-event-pooling for more information.

Использование OnChange б/н debouncer работает отлично.

+0

ли эта помощь? http://stackoverflow.com/q/23123138/870769 – sthzg

+0

Нет. Я пробовал это с помощью 'this.debouncedUriChangeHandler = _.debounce (this.uriChangeHandler, 500);' но получить ту же ошибку – Rob

ответ

2

в YOUT случае это может помочь

class HelloWorldComponent extends React.Component { 
    uriChangeHandler(target) { 
    console.log(target) 
    } 

    render() { 
    var myHandler = _.compose(
     _.debounce(this.uriChangeHandler.bind(this), 5e2), 
     _.property('target') 
    ); 
    return (  
     <input onChange={myHandler} /> 
    ); 
    } 
} 

React.render(
    <HelloWorldComponent/>, 
    document.getElementById('react_example') 
); 

JSBin

Также вы можете использовать _.clone вместо _.property('target'), если вы хотите получить полный объект события.

EDITED

Чтобы предотвратить Реагировать аннулирует событие, которое вы должны назвать event.persist(), как указано на React doc:

If you want to access the event properties in an asynchronous way, you should call event.persist() on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.

И, следовательно, вы могли бы использовать e => e.persist() || e вместо _.clone JSBin

+0

Это сделало трюк спасибо! Не могли бы вы объяснить, как? Я использовал бит '_.clone' вместо' _.property' – Rob

0

Я думаю, что происходит то, что событие аннулируется за время между фактическим событием и при вызове метода. Глядя на _.debounce source code (и используя то, что мы знаем о функциях debouncing), вы скажете, что ваш метод не вызывается до 500 миллисекунд до после события срабатывают. Так что у вас есть что-то подобное происходит:

  1. пожаров Событие
  2. _.debounce() устанавливает таймаут 500 миллисекунд
  3. Реагировать аннулирует event объект
  4. костров таймера и вызывает обработчик события
  5. Вы вызываете event.stopPropagation() по завершенному событию.

Я думаю, у вас есть два возможных решения: звоните event.stopPropagation() каждый раз, когда событие срабатывает (за пределами отказа) или вообще не вызывает его.

Боковое примечание: это все равно будет проблемой даже при использовании местных событий. К тому времени, когда ваш обработчик фактически вызван, событие уже распространилось бы. Реакт просто делает лучшую работу, предупреждая вас, что вы сделали что-то странное.

7

я закончил с решением, которое я видел на github, который хорошо работал для меня. В основном вы завершаете функцию debounce в пользовательской функции debounceEventHandler, которая будет сохраняться в событии перед возвратом функции debounced.

function debounceEventHandler(...args) { 
    const debounced = _.debounce(...args) 
    return function(e) { 
    e.persist() 
    return debounced(e) 
    } 
} 

<Input onChange={debounceEventHandler(this.handleInputChange, 150)}/> 

Это избавившись от синтетического предупреждение

1
class HelloWorldComponent extends Component { 
    _handleInputSearchChange = (event) => { 
     event.persist(); 
     _.debounce((event) => { 
      console.log(event.target.value); 
     }, 1000)(event); 
    }; 

    render() { 
     return (
      <input onChange={this._handleInputSearchChange} /> 
     ); 
    } 
} 
+0

, это так умно –

Смежные вопросы