我有搜索输入。
const { searchMails } = this.props;
searchMails(keyword);
我在Stack Overflow上添加了基于this answer的lodash debounce
。
const { searchMails } = this.props;
const debounceSearchMails = debounce(searchMails, 1000);
debounceSearchMails(keyword);
行动
export const searchMails = keyword => ({ type: SEARCH_MAILS, payload: keyword });
但是,添加debounce
后,当我输入“hello”时,它会在1秒后触发5次searchMails
。有效载荷是
h
he
hel
hell
hello
如何正确使用去抖?感谢
更新1 :添加完整代码
import React, { PureComponent } from 'react';
import { Field, reduxForm, reset } from 'redux-form';
import { Form } from 'reactstrap';
import debounce from 'lodash/debounce';
class Search extends PureComponent {
constructor(props) {
super(props);
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(values) {
const { searchMails } = this.props;
const debounceSearchMails = debounce(searchMails, 1000);
debounceSearchMails(values.keyword);
}
render() {
const { handleSubmit, keyword } = this.props;
return (
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Field name="keyword" component="input" type="search" onChange={() => setTimeout(handleSubmit(this.onSubmit))} />
</Form>
);
}
}
function validate(values) {
const errors = {};
return errors;
}
export default reduxForm({
validate,
form: 'searchForm'
})(Search);
更新2 :
我将行动改为
const searchMails0 = keyword => ({ type: SEARCH_MAILS, payload: keyword });
export const searchMails = debounce(searchMails0, 1000);
但仍然相同。
更新3 :这次我改为此,但仍然相同。
class Search extends PureComponent {
constructor(props) {
super(props);
this.onSubmit = this.onSubmit.bind(this);
this.debouncedSubmit = debounce(this.onSubmit, 1000);
}
onSubmit(values) {
const { searchMails } = this.props;
searchMails(values.keyword);
}
render() {
const { handleSubmit, keyword } = this.props;
return (
<Form onSubmit={handleSubmit(this.debouncedSubmit)}>
<Field name="keyword" component="input" type="search" onChange={() => setTimeout(handleSubmit(this.debouncedSubmit))} />
</Form>
);
}
}
UDPATE 4:
我发现问题与setTimeout
有某种关联,如果我有以下情况,debounce
将无效。如果我删除setTimeout
,debounce
将有效。但是onChange
将始终返回最后一个值。所以我确实需要它,因为redux-form的this "issue"
<Field component="input" type="search" onChange={() => setTimeout(handleSubmit(debounce(this.onSubmit, 1000)))}/>
答案 0 :(得分:5)
首先非常感谢@zerkms。如果没有正确方向的指导,我就无法做到。
您应该只创建一次去抖动功能,然后再使用它。它是去抖动功能,内部保持去抖所需的状态。目前,您在每次击键时重新创建它。 - zerkms
检查onChange's type后,这是最终的工作代码:
class Search extends PureComponent {
constructor(props) {
super(props);
this.onSubmit = this.onSubmit.bind(this);
this.onChange = this.onChange.bind(this);
this.debouncedOnChange = debounce(this.onChange, 1000);
}
onSubmit(values) {
const { searchMails } = this.props;
searchMails(values.keyword);
}
onChange(event, newValue, previousValue) {
const { searchMails } = this.props;
searchMails(newValue); // the second parameter is new value
}
render() {
const { keyword } = this.props;
return (
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Field component="input" type="search" onChange={this.debouncedOnChange}/>
</Form>
);
}
}
经验教训:
我从未想过我可以在构造函数中执行this.debouncedSubmit = debounce(this.onSubmit, 1000);
之类的操作。
我一直认为我必须使用redux-form中的handleSubmit
,但事实证明并非适用于所有情况。
需要深入。