Lodash debounce 在 React 中不起作用

新手上路,请多包涵

最好先看看我的代码:

 import React, { Component } from 'react';
import _ from 'lodash';
import Services from 'Services'; // Webservice calls

export default class componentName extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: this.props.value || null
    }
  }

  onChange(value) {
    this.setState({ value });

    // This doesn't call Services.setValue at all
    _.debounce(() => Services.setValue(value), 1000);
  }

  render() {
    return (
      <div>
        <input
          onChange={(event, value) => this.onChange(value)}
          value={this.state.value}
        />
      </div>
    )
  }
}

只是一个简单的输入。在构造函数中,它从道具(如果可用)处获取 value 为组件设置本地状态。

然后在 onChange 函数 input 更新状态,然后尝试调用 web 服务端点以使用 Services.setValue() 设置新值。

如果我直接通过输入的 onChange 设置 debounce ,就像这样:

 <input
  value={this.state.value}
  onChange={_.debounce((event, value) => this.onChange(value), 1000)}
/>

但是随后 this.setState 每 1000 毫秒才被调用一次并更新视图。因此,在文本字段中键入最终看起来很奇怪,因为您键入的内容只会在一秒钟后显示。

在这种情况下我该怎么办?

原文由 user818700 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

出现问题是因为你没有调用 debounce 函数,你可以通过以下方式进行

export default class componentName extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: this.props.value || null
    }
    this.servicesValue = _.debounce(this.servicesValue, 1000);
  }

  onChange(value) {
    this.setState({ value });
    this.servicesValue(value);
  }
  servicesValue = (value) => {
      Services.setValue(value)
  }
  render() {
    return (
      <div>
        <input
          onChange={(event, value) => this.onChange(value)}
          value={this.state.value}
        />
      </div>
    )
  }
}

原文由 Shubham Khatri 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于那些因为油门/去抖动不适用于 FunctionComponent 而来到这里的人的解决方案—你需要通过 useRef() 存储去抖动函数:

 export const ComponentName = (value = null) => {
  const [inputValue, setInputValue] = useState(value);

  const setServicesValue = value => Services.setValue(value);

  const setServicesValueDebounced = useRef(_.debounce(setServicesValue, 1000));

  const handleChange = ({ currentTarget: { value } }) => {
    setInputValue(value);
    setServicesValueDebounced.current(value);
  };

  return <input onChange={handleChange} value={inputValue} />;
};

这篇中篇文章 完美地解释了会发生什么:

函数内的局部变量在每次调用后都会过期。每次重新评估组件时,局部变量都会再次初始化。在幕后使用 window.setTimeout() 进行节流和去抖。每次评估功能组件时,您都会注册一个新的 setTimeout 回调。因此,我们将使用 useRef() 钩子,因为 useRef() 返回的值不会在每次执行功能组件时都重新计算。唯一的不便是您必须通过 .current 属性访问您的存储值。

我已经用微小的 lodash.throttlelodash.debounce 包创建了 沙箱,这样你就可以对两者进行试验并选择合适的行为

原文由 godblessstrawberry 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题