React Native:使用lodash debounce

时间:2016-12-18 17:16:31

标签: javascript reactjs react-native lodash

我正在玩React Native和lodash的辩护。

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

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

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

4 个答案:

答案 0 :(得分:43)

去抖函数应该在render方法之外的某个地方定义,因为每次调用它时它都必须引用函数的同一个实例,因为它反对创建一个新的实例,就像现在你把它放在{{1处理函数。

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

onChangeText

答案 1 :(得分:2)

2019:使用'useCallback'react钩子

尝试了许多不同的方法后,我发现使用“ 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();
 };

希望这会有所帮助!

答案 2 :(得分:0)

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

答案 3 :(得分:-2)

在这里您可以找到一个很好的使用方法示例:

import React, { useState } from 'react';
import _ from 'lodash';
import { fetchData } from '../../services/request';
import ResultListComponent from '../ResultList';

const SearchBarComponent = () => {
  const [query, setQuery] = useState('');
  const [searchQuery, setSearchQuery] = useState({});
  const [dataList, setDataList] = useState([]);
  const [errorMssg, setErrorMssg] = useState('');
  /**
   * This will be called every time there is
   * a change in the input
   * @param {*} { target: { value } }
   */
  const onChange = ({ target: { value } }) => {
    setQuery(value);
    // Here we set search var, so debounce will make sure to trigger 
    // the event every 300ms
    const search = _.debounce(sendQuery, 300);

    setSearchQuery(prevSearch => {
      // In case there is a previous search triggered,
      // cancel() will prevent previous method to be called 
      if (prevSearch.cancel) {
        prevSearch.cancel();
      }
      return search;
    });

    search(value);
  };

  /**
   * In charge to send the value
   * to the API.
   * @param {*} value
   */
  const sendQuery = async value => {
    const { cancelPrevQuery, result } = await fetchData(value);

    if (cancelPrevQuery) return;

    if (result.Response === 'True') {
      setDataList(result.Search);
      setErrorMssg('');
    } else {
      setDataList([]);
      setErrorMssg(result.Error);
    }
  };

  return (
    <div>
      <div>
        <p>Type to search!</p>
        <input type="text" value={query} placeholder="Enter Movie Title" onChange={onChange} />
      </div>
      <div>
        <ResultListComponent items={dataList} />
        {errorMssg}
      </div>
    </div>
  );
};

export default SearchBarComponent;

您可以参考我刚刚写的这篇中等文章:

https://medium.com/@mikjailsalazar/just-another-searchbar-react-axios-lodash-340efec6933d