I want to reduce my general dependency on useEffects and have created a hook file that fetches from an api
I have the following code setup:
const searchCharactersAPI = useCallback(async () => {
try {
setLoading(true);
const res = await fetch(
`https://narutodb.xyz/api/character${
search !== "" ? `/search?name=${search}` : ""
}`,
);
const resJSON = await res?.json();
setCharactersData(resJSON);
} catch (error) {
console.log("There was an error", error);
} finally {
setLoading(false);
}
}, [search]);
const handleSearch = (e: ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value)
}
<input className="flex w-full border-0 outline-none focus-visible:false rounded-lg p-2 text-black" placeholder="Search characters..." type="text" onChange={handleSearch} value={search} />
if i was to change the searchCharactersAPI useCallback fn to a useEffect it will work as expected but i am wondering why it doesnt fire when it is a useCallback when exact same dependencies
2
Answers
useCallback
doesn’t call the function every time a dependency changes. It just returns a new function reference. Either you have to call the function in theuseCallback
, or you have to call thesearchCharactersAPI
inhandleSearch
.On a side note, if you’re trying to remove effects from your code, then using
useCallback
to execute side effects is not the way to go. Handle user events in an event handler like you are supposed to.The useCallback hook memoizes the function instance and only changes it when its dependencies change. If the search state is not changing, the searchCharactersAPI function won’t be updated, and therefore, the effect won’t be triggered.
You can try using the useEffect hook directly and include search as a dependency in the dependency array.