【问题标题】:React Native: Using lodash debounceReact Native:使用 lodash 去抖动
【发布时间】:2017-05-03 19:30:30
【问题描述】:

我正在玩 React Native 和 lodash 的 debounce。

使用下面的代码只会让它像延迟而不是去抖动一样工作。

<Input
 onChangeText={(text) => {
  _.debounce(()=> console.log("debouncing"), 2000)()
 }
/>

如果我输入像“foo”这样的输入,我希望控制台只记录一次去抖动。现在它记录了 3 次“去抖动”。

【问题讨论】:

  • onChangeText 每次更改输入时都会调用,输入 foo 将使 debounce 函数调用 3 次,因此行为正确。
  • @jmac 我很确定问题总是在我身上????但是我想要它如何存档所以它只触发一次,触发后可以再次触发
  • _.debounce 创建了一个新函数,它应该作为回调直接传递,但是你已经将它包装在额外的函数中,并且每次发生变化时手动创建+调用去抖动函数的新实例。您应该消除这个额外的包装器:onChangeText={_.debounce((text) =&gt; console.log('debouncing', text), 2000)}。不用担心参数,它会将它们传递给您的处理程序。

标签: javascript reactjs react-native lodash


【解决方案1】:

Debounce 函数应该定义在 render 方法之外的某个地方,因为每次调用它时它都必须引用该函数的同一个实例,而不是像现在将它放在 onChangeText 中那样创建一个新实例。处理函数。

定义去抖动函数的最常见位置是在组件的对象上。这是一个例子:

class MyComponent extends React.Component {
  constructor() {
    this.onChangeTextDelayed = _.debounce(this.onChangeText, 2000);
  }

  onChangeText(text) {
    console.log("debouncing");
  }

  render() {
    return <Input onChangeText={this.onChangeTextDelayed} />
  }
}

【讨论】:

  • 如果您有任何理由立即调用去抖动函数(例如,当 onBlur 事件发生时),这非常适合。只需调用this.onChangeTextDelayed.flush(),就会立即跳过最后一次超时。
  • 去抖动少于 100 毫秒会使我的应用程序崩溃。其他人有这个问题吗?
【解决方案2】:

2019:使用“useCallback”反应钩子

在尝试了许多不同的方法后,我发现使用“useCallback”是解决多次调用问题的最简单和最有效的方法。

根据Hooks API documentation,“useCallback 返回回调的记忆版本,仅当其中一个依赖项发生更改时才会更改。”

将空数组作为依赖项传递可确保回调仅被调用一次。这是一个简单的实现。

import React, { useCallback } from "react";
import { debounce } from "lodash";

const handler = useCallback(debounce(someFunction, 2000), []);

const onChange = (event) => {
    // perform any event related action here

    handler();
 };

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    2021 年更新

    正如其他答案已经说明的那样,必须创建一次去抖动函数引用,并通过调用相同的引用来谴责相关函数(即我的示例中的 changeTextDebounced)。对@George Borunov 的回答稍作改动即可解决问题。

    class SomeClassComponent extends React.Component {
      componentDidMount = () => {
        this.changeTextDebouncer = _.debounce(this.changeTextDebounced, 500);
      }
    
      changeTextDebounced = (text) => {
        console.log("debounced");
      }
    
      render = () => {
        return <Input onChangeText={this.changeTextDebouncer} />;
      }
    }
    

    【讨论】:

    • 这对我们很有用,我们已经把头砸了好几个小时,按钮被按下时触发了太多次
    • 在使用功能组件时有人可以帮我解决这个问题
    • 如果您正在为功能组件寻找相同的东西,您应该尝试@Sameer Ingavale 的回答。
    猜你喜欢
    • 2016-07-17
    • 2021-07-16
    • 2015-05-21
    • 2017-07-08
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多