React Native: Using lodash debounce

白昼怎懂夜的黑 提交于 2019-11-28 22:49:20

问题


I'm playing around with React Native and lodash's debounce.

Using the following code only make it work like a delay and not a debounce.

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

I want the console to log debounce only once if I enter an input like "foo". Right now it logs "debounce" 3 times.


回答1:


Debounce function should be defined somewhere outside of render method since it has to refer to the same instance of the function every time you call it as oppose to creating a new instance like it's happening now when you put it in the onChangeText handler function.

The most common place to define a debounce function is right on the component's object. Here's an example:

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

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

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



回答2:


2019: Use the 'useCallback' react hook

After trying many different approaches, I found using 'useCallback' to be the simplest and most efficient at solving the multiple calls problem.

As per the Hooks API documentation, "useCallback returns a memorized version of the callback that only changes if one of the dependencies has changed."

Passing an empty array as a dependency makes sure the callback is called only once. Here's a simple implementation.

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();
 };

Hope this helps!




回答3:


Here you can find a good example of how to use it:

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;

You can refer this medium article I just did:

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



来源:https://stackoverflow.com/questions/41210867/react-native-using-lodash-debounce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!