我有一个需要去抖动的字段的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);
}
我收到此错误: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工作正常。
答案 0 :(得分:8)
我最终得到了一个我在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 :(得分:2)
在你的情况下它可能有所帮助
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')
);
如果您想获取完整的事件对象,也可以使用_.clone
代替_.property('target')
。
<强> EDITED 强>
为了防止React使活动无效,您必须按照React doc上的说明致电event.persist()
:
如果要以异步方式访问事件属性,则应在事件上调用event.persist(),这将从池中删除合成事件,并允许用户代码保留对事件的引用。
因此您可以使用e => e.persist() || e
代替_.clone
JSBin
答案 2 :(得分:2)
const MyComponent = () => {
const handleChange = useMemo(() => {
const debounced = _.debounce(e => console.log(e.target.value), 1000);
return e => {
e.persist();
return debounced(e);
};
}, []);
return <input onChange={handleChange} />;
};
答案 3 :(得分:0)
我认为发生的事件是事件在实际事件和调用方法之间的时间内无效。查看_.debounce
source code(并使用我们对debouncing函数的了解)将告诉您,在事件触发后 事件发生后,您的方法才会被调用,直到500毫秒为止。所以你有这样的事情发生了:
_.debounce()
设置500毫秒超时event
对象event.stopPropagation()
。我认为您有两种可能的解决方案:每次事件发生时(在去抖动之外)拨打event.stopPropagation()
,或者根本不打电话。
旁注:即使使用原生事件,这仍然是一个问题。当您的处理程序实际被调用时,该事件已经传播。 React正在更好地警告你,你已经做了一些奇怪的事情。
答案 4 :(得分:0)
class HelloWorldComponent extends Component {
_handleInputSearchChange = (event) => {
event.persist();
_.debounce((event) => {
console.log(event.target.value);
}, 1000)(event);
};
render() {
return (
<input onChange={this._handleInputSearchChange} />
);
}
}
答案 5 :(得分:0)
这里的想法是我们希望onChange处理程序先保存事件然后立即去除我们的事件处理程序,这可以通过以下代码简单地实现:
<input
onChange={_.flowRight(
_.debounce(this.handleOnChange.bind(this), 300),
this.persistEvent,
)}
</input>
persistEvent = e => {
e.persist();
e.preventDefault();
return e;
};
handleOnChange = e => {
console.log('event target', e.target);
console.log('state', this.state);
// here you can add you handler code
}