如何在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
}
});
你试过吗?
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);
}
});
I was searching for a solution to the same problem and came across this thread as well as some others but they had the same problem: if you are trying to do a handleOnChange function and you need the value from an event target, you will get cannot read property value of null or some such error. In my case, I also needed to preserve the context of this inside the debounced function since I'm executing a fluxible action. Here's my solution, it works well for my use case so I'm leaving it here in case anyone comes across this thread:
// at top of file:
var myAction = require('../actions/someAction');
// inside React.createClass({...});
handleOnChange: function (event) {
var value = event.target.value;
var doAction = _.curry(this.context.executeAction, 2);
// only one parameter gets passed into the curried function,
// so the function passed as the first parameter to _.curry()
// will not be executed until the second parameter is passed
// which happens in the next function that is wrapped in _.debounce()
debouncedOnChange(doAction(myAction), value);
},
debouncedOnChange: _.debounce(function(action, value) {
action(value);
}, 300)
FYI
这是另一个PoC实现:
没有任何库(例如lodash)用于debound
使用React Hooks API
我希望它能帮助你:)
import React, { useState, useEffect, ChangeEvent } from 'react';
export default function DebouncedSearchBox({
inputType,
handleSearch,
placeholder,
debounceInterval,
}: {
inputType?: string;
handleSearch: (q: string) => void;
placeholder: string;
debounceInterval: number;
}) {
const [query, setQuery] = useState<string>('');
const [timer, setTimer] = useState<NodeJS.Timer | undefined>();
useEffect(() => {
if (timer) {
clearTimeout(timer);
}
setTimer(setTimeout(() => {
handleSearch(query);
}, debounceInterval));
}, [query]);
const handleOnChange = (e: ChangeEvent<HTMLInputElement>): void => {
setQuery(e.target.value);
};
return (
<input
type={inputType || 'text'}
className="form-control"
placeholder={placeholder}
value={query}
onChange={handleOnChange}
/>
);
}
您可以使用引用变量来存储计时器,然后将其清除。下面是一个不使用任何第三方包在react中实现deboundation的例子
import { useState, useRef } from "react";
import "./styles.css";
export default function App() {
// Variables for debouncing
const [text, setText] = useState("");
const timer = useRef();
// Variables for throtteling
const [throttle, setThrottle] = useState(false)
const handleDebouncing = ({ target }) => {
clearTimeout(timer.current)
timer.current = setTimeout(() => {
callApi();
}, 300);
setText(target.value);
};
const handleThrottleing = () => {
callApi()
setThrottle(true)
setTimeout(() => {
setThrottle(false)
}, 2000)
}
const callApi = () => {
console.log("Calling Api");
};
return (
<div className="App">
<input type="text" onChange={handleDebouncing} />
<button onClick={handleThrottleing} disabled={throttle} >Click me to see throtteling</button>
</div>
);
}