Дебют Лодаша с использованием React Input

Я пытаюсь добавить debouncing с lodash в функцию поиска, вызванную из события onChange. В приведенном ниже коде генерируется ошибка типа "ожидается функция", что я понимаю, потому что lodash ожидает функцию. Каков правильный способ сделать это, и может ли это сделать все встроенное? Я пробовал почти каждый пример до сих пор на SO безрезультатно.

search(e){
 let str = e.target.value;
 debounce(this.props.relay.setVariables({ query: str }), 500);
},

Ответ 1

Функция debounce может быть встроена в JSX или установлена непосредственно как метод класса, как показано здесь:

search: _.debounce(function(e) {
  console.log('Debounced Event:', e);
}, 1000)

Скрипка: https://jsfiddle.net/woodenconsulting/69z2wepo/36453/

Если вы используете es2015+, вы можете определить свой метод debounce напрямую, в constructor или в методе жизненного цикла, например componentWillMount.

Примеры:

class DebounceSamples extends React.Component {
  constructor(props) {
    super(props);

    // Method defined in constructor, alternatively could be in another lifecycle method
    // like componentWillMount
    this.search = _.debounce(e => {
      console.log('Debounced Event:', e);
    }, 1000);
  }

  // Define the method directly in your class
  search = _.debounce((e) => {
    console.log('Debounced Event:', e);
  }, 1000)
}

Ответ 2

Это не так просто вопрос

С одной стороны, чтобы просто обойти ошибку, которую вы получаете, вам нужно обернуть вас setVariables в функции:

 search(e){
  let str = e.target.value;
  _.debounce(() => this.props.relay.setVariables({ query: str }), 500);
}

С другой стороны, я верю, что логика debouncing должна быть инкапсулирована внутри Relay.

Ответ 3

Вот как я должен был это сделать после того, как весь день гуглил.

const MyComponent = (props) => {
  const [reload, setReload] = useState(false);

  useEffect(() => {
    if(reload) { /* Call API here */ }
  }, [reload]);

  const callApi = () => { setReload(true) }; // You might be able to call API directly here, I haven't tried
  const [debouncedCallApi] = useState(() => _.debounce(callApi, 1000));

  function handleChange() { 
    debouncedCallApi(); 
  }

  return (<>
    <input onChange={handleChange} />
  </>);
}