FD3
FD3

Reputation: 1946

How to implement debounce in React.js?

I am trying to implement debounce on search.
The idea is to send a request to the api once user stopped typing.
I have a working example, which works fine. You can see there that typed value will be printed on the screen once finished typing
Now I am trying to implement the same feature on the same input with search functionality, but it doesn't work and throws an error:

TypeError: Cannot read properties of null (reading 'value')

Here is the component and the sandbox link

import React, { useState } from "react";
import data from "./MOCK_DATA.json";
function App() {
  const [name, setName] = useState("");
  const debounce = (func, delay) => {
    let timer;
    return (...arg) => {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        func(...arg);
      }, delay);
    };
  };

  const onChangeHandler = (e) => {
    setName(e.target.value);
  };

  const debouncedOnChangeHandler = debounce(onChangeHandler, 1000);

  const filteredData = data.filter((el) =>
    el.first_name.toLowerCase().includes(name.toLowerCase())
  );
  return (
    <div>
      <div style={{ width: "100%" }}>Search</div>
      <input
        value={name}
        onChange={debouncedOnChangeHandler} //debouncedOnChangeHandler doesn't work because value is asynchronous
        //onChange={onChangeHandler} //this works fine without debounce function
        type="text"
        placeholder="search"
      />
      {filteredData &&
        filteredData.map((el) => <div key={el.id}>{el.first_name}</div>)}
    </div>
  );
}

export default App;

Any help will be appreciated.

Upvotes: 0

Views: 621

Answers (1)

Maniraj Murugan
Maniraj Murugan

Reputation: 9084

There are some changes which you need to make,

First debouncedOnChangeHandler variable holds the function like,

   const debouncedOnChangeHandler = (e) => {
    debounce(onChangeHandler(e), 1000);
   };

But whereas this doesn't pass the onChangeHandler as expected argument for debounce method.

So you need to just passdown the debounce function along with required parameters like,

const debouncedOnChangeHandler = debounce(onChangeHandler, 1000);

Second: You need to remove value={name} which is not needed in this context.

Forked Codesanbox:

Edit mutable-mountain-ec3q9j

Upvotes: 3

Related Questions