如何在React.js中执行debounce ?
我想撤消handleOnChange。
我尝试debounce(这。handleOnChange, 200)但它不起作用。
function debounce(fn, delay) {
var timer = null;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
};
}
var SearchBox = React.createClass({
render: function() {
return <input type="search" name="p" onChange={this.handleOnChange} />;
},
handleOnChange: function(event) {
// make ajax call
}
});
不受控制的组件
你可以使用event.persist()方法。
下面是一个使用下划线_.debounce()的例子:
var SearchBox = React.createClass({
componentWillMount: function () {
this.delayedCallback = _.debounce(function (event) {
// `event.target` is accessible now
}, 1000);
},
onChange: function (event) {
event.persist();
this.delayedCallback(event);
},
render: function () {
return (
<input type="search" onChange={this.onChange} />
);
}
});
编辑:请看这个JSFiddle
控制组件
更新:上面的例子显示了一个不受控制的组件。我一直在使用受控元素,这里是上面的另一个例子,但没有使用event.persist()“欺骗”。
JSFiddle也是可用的。不带下划线的示例
var SearchBox = React.createClass({
getInitialState: function () {
return {
query: this.props.query
};
},
componentWillMount: function () {
this.handleSearchDebounced = _.debounce(function () {
this.props.handleSearch.apply(this, [this.state.query]);
}, 500);
},
onChange: function (event) {
this.setState({query: event.target.value});
this.handleSearchDebounced();
},
render: function () {
return (
<input type="search"
value={this.state.query}
onChange={this.onChange} />
);
}
});
var Search = React.createClass({
getInitialState: function () {
return {
result: this.props.query
};
},
handleSearch: function (query) {
this.setState({result: query});
},
render: function () {
return (
<div id="search">
<SearchBox query={this.state.result}
handleSearch={this.handleSearch} />
<p>You searched for: <strong>{this.state.result}</strong></p>
</div>
);
}
});
React.render(<Search query="Initial query" />, document.body);
编辑:更新示例和JSFiddles到React 0.12
编辑:更新的例子,以解决Sebastien Lorber提出的问题
编辑:更新的jsfiddle不使用下划线和使用纯javascript debounce。
你也可以使用自己编写的mixin,就像这样:
var DebounceMixin = {
debounce: function(func, time, immediate) {
var timeout = this.debouncedTimeout;
if (!timeout) {
if (immediate) func();
this.debouncedTimeout = setTimeout(function() {
if (!immediate) func();
this.debouncedTimeout = void 0;
}.bind(this), time);
}
}
};
然后像这样在你的组件中使用它:
var MyComponent = React.createClass({
mixins: [DebounceMixin],
handleClick: function(e) {
this.debounce(function() {
this.setState({
buttonClicked: true
});
}.bind(this), 500, true);
},
render: function() {
return (
<button onClick={this.handleClick}></button>
);
}
});
有点晚了,但应该有帮助。
创建这个类(它是用typescript写的,但是很容易转换成javascript)
export class debouncedMethod<T>{
constructor(method:T, debounceTime:number){
this._method = method;
this._debounceTime = debounceTime;
}
private _method:T;
private _timeout:number;
private _debounceTime:number;
public invoke:T = ((...args:any[])=>{
this._timeout && window.clearTimeout(this._timeout);
this._timeout = window.setTimeout(()=>{
(this._method as any)(...args);
},this._debounceTime);
}) as any;
}
要使用
var foo = new debouncedMethod((name,age)=>{
console.log(name,age);
},500);
foo.invoke("john",31);