Reputation: 1946
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
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:
Upvotes: 3