使用debouncer与React事件

Rob*_*Rob 7 javascript javascript-events underscore.js debouncing reactjs

我有一个需要去抖动的字段的onchange事件,我正在使用下划线,但是当我使用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);
}
Run Code Online (Sandbox Code Playgroud)

我收到这个错误: 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 w/o debouncer工作正常.

xia*_*lin 9

我最终得到了一个我在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)}/>
Run Code Online (Sandbox Code Playgroud)

这摆脱了合成事件警告


小智 4

在你的情况下可能会有所帮助

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

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

React.render(
  <HelloWorldComponent/>,
  document.getElementById('react_example')
);
Run Code Online (Sandbox Code Playgroud)

杰士宾

如果你想获得完整的事件对象,你也可以使用_.clone而不是。_.property('target')

编辑

为了防止 React 使事件无效,您必须event.persist()按照React 文档中的说明调用:

如果要以异步方式访问事件属性,则应该对事件调用 event.persist() ,这将从池中删除合成事件,并允许用户代码保留对事件的引用。

因此你可以使用JSBine => e.persist() || e代替_.clone