如何在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
}
});
在与文本输入斗争了一段时间后,我自己没有找到一个完美的解决方案,我在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上试试吧
我希望这也能帮助其他人,节省他们的时间。
我发现Justin Tulk的这篇文章很有帮助。在经过几次尝试后,人们会认为这是react/redux更正式的方式,结果显示它失败了,因为react的合成事件池。然后,他的解决方案使用一些内部状态来跟踪在输入中更改/输入的值,在setState之后使用一个回调,调用一个throttled/ deboundredux动作,实时显示一些结果。
import React, {Component} from 'react'
import TextField from 'material-ui/TextField'
import { debounce } from 'lodash'
class TableSearch extends Component {
constructor(props){
super(props)
this.state = {
value: props.value
}
this.changeSearch = debounce(this.props.changeSearch, 250)
}
handleChange = (e) => {
const val = e.target.value
this.setState({ value: val }, () => {
this.changeSearch(val)
})
}
render() {
return (
<TextField
className = {styles.field}
onChange = {this.handleChange}
value = {this.props.value}
/>
)
}
}
这个解决方案不需要任何额外的库,它也会在用户按下enter时启动:
const debounce = (fn, delay) => {
let timer = null;
return function() {
const context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, args);
}, delay);
};
}
const [search, setSearch] = useState('');
const [searchFor, setSearchFor] = useState(search);
useEffect(() => {
console.log("Search:", searchFor);
}, [searchFor]);
const fireChange = event => {
const { keyCode } = event;
if (keyCode === 13) {
event.preventDefault();
setSearchFor(search);
}
}
const changeSearch = event => {
const { value } = event.target;
setSearch(value);
debounceSetSearchFor(value);
};
const debounceSetSearchFor = useCallback(debounce(function(value) {
setSearchFor(value);
}, 250), []);
输入可以是这样的:
<input value={search} onKeyDown={fireChange} onChange={changeSearch} />
对于debounce,你需要在event.persist()中保留原始的合成事件。下面是用React 16+测试的工作示例。
import React, { Component } from 'react';
import debounce from 'lodash/debounce'
class ItemType extends Component {
evntHandler = debounce((e) => {
console.log(e)
}, 500);
render() {
return (
<div className="form-field-wrap"
onClick={e => {
e.persist()
this.evntHandler(e)
}}>
...
</div>
);
}
}
export default ItemType;
使用功能组件,您可以做到这一点-
const Search = ({ getBooks, query }) => {
const handleOnSubmit = (e) => {
e.preventDefault();
}
const debouncedGetBooks = debounce(query => {
getBooks(query);
}, 700);
const onInputChange = e => {
debouncedGetBooks(e.target.value)
}
return (
<div className="search-books">
<Form className="search-books--form" onSubmit={handleOnSubmit}>
<Form.Group controlId="formBasicEmail">
<Form.Control type="text" onChange={onInputChange} placeholder="Harry Potter" />
<Form.Text className="text-muted">
Search the world's most comprehensive index of full-text books.
</Form.Text>
</Form.Group>
<Button variant="primary" type="submit">
Search
</Button>
</Form>
</div>
)
}
引用- - - - - -
——https://gist.github.com/elijahmanor/08fc6c8468c994c844213e4a4344a709
——https://blog.revathskumar.com/2016/02/reactjs-using-debounce-in-react-components.html