I am importing just the debounce function from lodash:
import debounce from "lodash/debounce"
the function I wish to debounce is an async function called ‘fetchUsers’. So I am creating the debounced version of the function thusly:
const debouncedFetchUsers = debounce(fetchUsers, 5000)
This gets called from a useEffect when the inputValue changes:
useEffect(() => {
if (inputValue.length > 2) {
debouncedFetchUsers(inputValue);
} else {
setUsers([]);
}
}, [inputValue, debouncedFetchUsers]);
If I type 5 characters into the inputValue text field in quick succession, the fetchUsers function is getting called (with correct inputValue
) 3 times ….after a delay of 5 seconds from each character press.
Of note, if I include debouncedFetchUsers
in my useEffect dependency array, I get an infinite re-render loop. This makes me think the function is getting re-created every render.
That brings me to the answer of Lodash debounce in react so then I wrap my debouncedFetchUsers
in a useCallback, thusly:
const debouncedFetchUsers = useCallback(
debounce(fetchUsers, 5000),
[fetchUsers]
);
This doesn’t fix the infinite useEffect loop.
So, I followed up the chain and wrapped fetchUsers
in a useCallback. This solved the issue.
For completeness, this is the fetchUsers
function:
const fetchUsers = useCallback(async (needle) => {
console.log(`FetchingUsers...${needle}`);
setIsLoading(true);
const response = await fetch(`http://localhost:7000/users?needle=${needle}`);
const data = await response.json();
setUsers(data);
setIsLoading(false);
console.log(`DONE FetchingUsers...${needle}`);
}, []);
.
2
Answers
Always make sure the dependency arrays are populated correctly. You ESlint configured with right rules for react hooks like exhaustive dependency rule to get all the dependencies right.
You might need to pass fetchUsers function as a dependency in the useCallback, like below:
If you want to avoid this you can directly write the function logic in the use callback:
Also the useEffect should have the memoized callback as a dependency:
See if this works