【问题标题】:How to use debounce with redux-form correctly?如何正确使用带有 redux-form 的 debounce?
【发布时间】:2017-10-29 07:05:32
【问题描述】:

我有一个搜索输入。

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

如何正确使用 debounce?谢谢

更新 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);

但还是一样。

UPDATE 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 将不起作用。如果我删除setTimeoutdebounce 将起作用。但随后onChange 将始终返回最后一个值。所以我确实需要它,因为 redux-form 的 this "issue"

<Field component="input" type="search" onChange={() => setTimeout(handleSubmit(debounce(this.onSubmit, 1000)))}/>

【问题讨论】:

  • 显示您的组件和事件处理程序。
  • @zerkms 完成!只需添加
  • 你应该只创建一次去抖动函数然后使用它。它是 debounced 函数,它在内部保持 debounce 所需的状态。目前,您在每次击键时都重新创建它。
  • @zerkms 哦,谢谢。检查我的新更新。我改变了我的动作,但还是一样。也许我的用法仍然是错误的。你介意提些建议吗?
  • @zerkms 我试过onChange={() =&gt; handleSubmit(debounce(this.onSubmit, 1000))},它非常适合去抖动,但是没有setTimeout,我无法在onChange 中获得最新值。我必须找到一种方法让 debounce 工作并在 onChange 中获得最新值。

标签: javascript reactjs redux lodash


【解决方案1】:

首先非常感谢@zerkms。没有他正确方向的指导,我无法做到。

您应该只创建一次去抖动函数然后使用它。它是 debounced 函数,它在内部保持 debounce 所需的状态。目前,您在每次击键时都重新创建它。 - 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,但事实证明并非适用于所有情况。

  • 需要深入。

【讨论】:

  • > “需要深入。” ??
  • 你可以通过在 onSubmit() 和 onChange() 上使用箭头函数来保存那些 bind()ings
  • 这不是去抖动字段输入体验吗?
猜你喜欢
  • 2018-05-13
  • 2017-12-24
  • 2022-01-22
  • 1970-01-01
  • 2016-08-21
  • 2019-11-19
  • 1970-01-01
  • 1970-01-01
  • 2018-01-05
相关资源
最近更新 更多