lodash debounce in React functional component not working

前端 未结 3 1795
日久生厌
日久生厌 2021-02-01 04:03

I have a functional component built around the React Table component that uses the Apollo GraphQL client for server-side pagination and searching. I am trying to implement debou

相关标签:
3条回答
  • 2021-02-01 04:30

    debounceLoadData will be a new function for every render. You can use the useCallback hook to make sure that the same function is being persisted between renders and it will work as expected.

    useCallback(debounce(loadData, 1000), []);
    

    const { useState, useCallback } = React;
    const { debounce } = _;
    
    function App() {
      const [filter, setFilter] = useState("");
      const debounceLoadData = useCallback(debounce(console.log, 1000), []);
    
      function handleFilterChange(event) {
        const { value } = event.target;
    
        setFilter(value);
        debounceLoadData(value);
      }
    
      return <input value={filter} onChange={handleFilterChange} />;
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
    <div id="root"></div>

    0 讨论(0)
  • 2021-02-01 04:38

    You must remember the debounced function between renders.

    However, you should not use useCallback to remember a debounced (or throttled) function as suggested in other answers. useCallback is designed for inline functions!

    Instead use useMemo to remember the debounced function between renders:

    useMemo(() => debounce(loadData, 1000), []);
    
    0 讨论(0)
  • 2021-02-01 04:40

    To add onto Tholle's answer: if you want to make full use of hooks, you can use the useEffect hook to watch for changes in the filter and run the debouncedLoadData function when that happens:

    const { useState, useCallback, useEffect } = React;
    const { debounce } = _;
    
    function App() {
      const [filter, setFilter] = useState("");
      const debounceLoadData = useCallback(debounce(fetchData, 1000), []);
    
      useEffect(() => {
        debounceLoadData(filter);
      }, [filter]);
    
      function fetchData(filter) {
        console.log(filter);
      }
    
      return <input value={filter} onChange={event => setFilter(event.target.value)} />;
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    
    0 讨论(0)
提交回复
热议问题