React Native:使用 lodash debounce

问题描述 投票:0回答:5

我正在尝试 React Native 和 lodash 的 debounce。

使用以下代码只会使其像延迟一样工作,而不是去抖。

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

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

javascript reactjs react-native lodash
5个回答
82
投票

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} />
  }
}

51
投票

使用“useCallback”反应钩子

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

根据 Hooks API 文档,“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();
 };

6
投票

正如其他答案已经指出的那样,去抖函数引用必须创建一次,并通过调用相同的引用来谴责相关函数(即我的示例中的

changeTextDebounced
)。

首先要导入

import {debounce} from 'lodash';

对于类组件

class SomeClassComponent extends React.Component {
  componentDidMount = () => {
    this.changeTextDebouncer = debounce(this.changeTextDebounced, 500);
  }

  changeTextDebounced = (text) => {
    console.log("debounced");
  }

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

对于功能组件

const SomeFnComponent = () => {
  const changeTextDebouncer = useCallback(debounce(changeTextDebounced, 500), []);

  const changeTextDebounced = (text) => {
    console.log("debounced");
  }

  return <Input onChangeText={changeTextDebouncer} />;
}

0
投票

功能组件工作方案:

  import {debounce} from 'lodash';

  const [text, settext] = useState('');

  <TextInput
          style={styles.textInput}
          numberOfLines={1}
          placeholder={placeholder}
          placeholderTextColor={COLOR_GRAY_510}
          onChangeText={handleChange}
          value={text}
        />

----------------------------------------------
  const handleChange = async textParam => {
      settext(textParam);
      debounceCall(textParam);
  };

  const debounceCall = useCallback(
    debounce(textParam => {
      searchAPICall(textParam);
    }, 500),
    [],
  );

  const searchAPICall = async textParam => {
    if (textParam.length > 2) {
      let suggestions = await suggestAddressList(textParam);
      setresultList(suggestions.length > 0 ? suggestions : []);
    } else {
      setresultList([]);
    }
  };

0
投票

我在 textInput 中遇到了同样的问题,我的正则表达式被调用了太多次。我使用下面的代码来避免这个问题:

  const emailReg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w\w+)+$/;

  const debounceReg = useCallback(debounce((text: string) => {
    if (emailReg.test(text)) {
      setIsValidEmail(true);
    } else {
      setIsValidEmail(false);
    }
  }, 800), []);

  const onChangeHandler = (text: string) => {
    setEmailAddress(text);
    debounceReg(text)
  };

我的 utils 中的去抖代码是

function debounce<Params extends any[]>(
    f: (...args: Params) => any,
    delay: number,
): (...args: Params) => void {
    let timer: NodeJS.Timeout;

    return (...args: Params) => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            f(...args);
        }, delay);
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.