admin管理员组文章数量:1336367
I have a search input.
const { searchMails } = this.props;
searchMails(keyword);
I added the lodash's debounce
based on this answer on Stack Overflow.
const { searchMails } = this.props;
const debounceSearchMails = debounce(searchMails, 1000);
debounceSearchMails(keyword);
The action
export const searchMails = keyword => ({ type: SEARCH_MAILS, payload: keyword });
However, after adding debounce
, when I type "hello", it will still trigger 5 times searchMails
after 1 second. The payload are
h
he
hel
hell
hello
How can I use debounce correctly? Thanks
UPDATE 1: add full codes
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" ponent="input" type="search" onChange={() => setTimeout(handleSubmit(this.onSubmit))} />
</Form>
);
}
}
function validate(values) {
const errors = {};
return errors;
}
export default reduxForm({
validate,
form: 'searchForm'
})(Search);
UPDATE 2:
I changed my action to
const searchMails0 = keyword => ({ type: SEARCH_MAILS, payload: keyword });
export const searchMails = debounce(searchMails0, 1000);
But still same.
UPDATE 3: this time I changed to this, but still same.
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" ponent="input" type="search" onChange={() => setTimeout(handleSubmit(this.debouncedSubmit))} />
</Form>
);
}
}
UDPATE 4:
I found the issue is somehow related with setTimeout
, if I have that like below, debounce
won't work. If I remove setTimeout
, debounce
will work. But then onChange
will always return last value. So I do need have it because of redux-form's this "issue"
<Field ponent="input" type="search" onChange={() => setTimeout(handleSubmit(debounce(this.onSubmit, 1000)))}/>
I have a search input.
const { searchMails } = this.props;
searchMails(keyword);
I added the lodash's debounce
based on this answer on Stack Overflow.
const { searchMails } = this.props;
const debounceSearchMails = debounce(searchMails, 1000);
debounceSearchMails(keyword);
The action
export const searchMails = keyword => ({ type: SEARCH_MAILS, payload: keyword });
However, after adding debounce
, when I type "hello", it will still trigger 5 times searchMails
after 1 second. The payload are
h
he
hel
hell
hello
How can I use debounce correctly? Thanks
UPDATE 1: add full codes
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" ponent="input" type="search" onChange={() => setTimeout(handleSubmit(this.onSubmit))} />
</Form>
);
}
}
function validate(values) {
const errors = {};
return errors;
}
export default reduxForm({
validate,
form: 'searchForm'
})(Search);
UPDATE 2:
I changed my action to
const searchMails0 = keyword => ({ type: SEARCH_MAILS, payload: keyword });
export const searchMails = debounce(searchMails0, 1000);
But still same.
UPDATE 3: this time I changed to this, but still same.
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" ponent="input" type="search" onChange={() => setTimeout(handleSubmit(this.debouncedSubmit))} />
</Form>
);
}
}
UDPATE 4:
I found the issue is somehow related with setTimeout
, if I have that like below, debounce
won't work. If I remove setTimeout
, debounce
will work. But then onChange
will always return last value. So I do need have it because of redux-form's this "issue"
<Field ponent="input" type="search" onChange={() => setTimeout(handleSubmit(debounce(this.onSubmit, 1000)))}/>
Share
Improve this question
edited Oct 29, 2017 at 9:01
Hongbo Miao
asked Oct 29, 2017 at 7:05
Hongbo MiaoHongbo Miao
50k67 gold badges198 silver badges327 bronze badges
23
- 1 Show your ponent and an event handler. – zerkms Commented Oct 29, 2017 at 7:09
- @zerkms done! just add – Hongbo Miao Commented Oct 29, 2017 at 7:14
- 2 You should only create the debounced function once and then use it. It is debounced function that holds internally the state necessary for debouncing. At the moment you recreate it on every keystroke. – zerkms Commented Oct 29, 2017 at 7:15
- @zerkms oh, thanks. check my new update. I changed my action, but still same. Maybe my usage is still wrong. Would you mind giving some suggestions? – Hongbo Miao Commented Oct 29, 2017 at 7:27
-
1
@zerkms I tried
onChange={() => handleSubmit(debounce(this.onSubmit, 1000))}
, which works perfect for debounce, but then withoutsetTimeout
, I cannot get latest value in onChange. I have to find a way making both debounce work and also get latest value in onChange. – Hongbo Miao Commented Oct 29, 2017 at 8:59
1 Answer
Reset to default 7First big thank you for @zerkms. Without his guide to the right direction, I cannot make it.
You should only create the debounced function once and then use it. It is debounced function that holds internally the state necessary for debouncing. At the moment you recreate it on every keystroke. – zerkms
After checking onChange's type, this is final working code:
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 ponent="input" type="search" onChange={this.debouncedOnChange}/>
</Form>
);
}
}
Lessons learned:
I never thought I can do something like
this.debouncedSubmit = debounce(this.onSubmit, 1000);
in constructor.And I always thought I have to use
handleSubmit
from redux-form, but turns out it is not for all cases.Need go deep.
本文标签: javascriptHow to use debounce with reduxform correctlyStack Overflow
版权声明:本文标题:javascript - How to use debounce with redux-form correctly? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742405683a2468770.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论