如何在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
}
});
您可以使用Lodash debounce https://lodash.com/docs/4.17.5#debounce方法。它简单有效。
import * as lodash from lodash;
const update = (input) => {
// Update the input here.
console.log(`Input ${input}`);
}
const debounceHandleUpdate = lodash.debounce((input) => update(input), 200, {maxWait: 200});
doHandleChange() {
debounceHandleUpdate(input);
}
您还可以使用下面的方法取消debounce方法。
this.debounceHandleUpdate.cancel();
希望对你有所帮助。干杯! !
在与文本输入斗争了一段时间后,我自己没有找到一个完美的解决方案,我在npm上发现了这个:react-debounce-input。
这里有一个简单的例子:
import React from 'react';
import ReactDOM from 'react-dom';
import {DebounceInput} from 'react-debounce-input';
class App extends React.Component {
state = {
value: ''
};
render() {
return (
<div>
<DebounceInput
minLength={2}
debounceTimeout={300}
onChange={event => this.setState({value: event.target.value})} />
<p>Value: {this.state.value}</p>
</div>
);
}
}
const appRoot = document.createElement('div');
document.body.appendChild(appRoot);
ReactDOM.render(<App />, appRoot);
DebounceInput组件接受您可以分配给普通输入元素的所有道具。在codeen上试试吧
我希望这也能帮助其他人,节省他们的时间。
如果你正在使用redux,你可以通过中间件以一种非常优雅的方式做到这一点。你可以这样定义Debounce中间件:
var timeout;
export default store => next => action => {
const { meta = {} } = action;
if(meta.debounce){
clearTimeout(timeout);
timeout = setTimeout(() => {
next(action)
}, meta.debounce)
}else{
next(action)
}
}
然后你可以添加debounging到动作创建者,比如:
export default debouncedAction = (payload) => ({
type : 'DEBOUNCED_ACTION',
payload : payload,
meta : {debounce : 300}
}
实际上已经有中间件你可以脱离npm来为你做这件事。
你也可以使用自己编写的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>
);
}
});
如果你只需要在一个按钮中执行一个请求数据的debounce,提供的代码可能对你有帮助:
创建一个函数,以防止在请求为真或假时使用默认的条件语句
实现useState钩子和useEffect钩子
const PageOne = () => {
const [requesting, setRequesting] = useState(false);
useEffect(() => {
return () => {
setRequesting(false);
};
}, [requesting]);
const onDebounce = (e) => {
if (requesting === true) {
e.preventDefault();
}
// ACTIONS
setLoading(true);
};
return (
<div>
<button onClick={onDebounce}>Requesting data</button>
</div>
)
}
你试过吗?
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) {
debounce(\\ Your handleChange code , 200);
}
});