React Native: использование lodash debounce

Я играю с React Native и lodash debounce.

Использование следующего кода только заставляет его работать как задержка, а не отвал.

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

Я хочу, чтобы консоль регистрировала debounce только один раз, если я введу вход, подобный "foo". Сейчас он регистрирует "debounce" 3 раза.

Ответ 1

Функция Debounce должна быть определена где-то вне метода render, поскольку она должна ссылаться на тот же экземпляр функции каждый раз, когда вы вызываете ее как против создания нового экземпляра, как это происходит сейчас, когда вы помещаете его в onChangeText обработчика.

Наиболее распространенное место для определения функции debounce - прямо на объекте компонента. Вот пример:

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

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

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

Ответ 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