Issue
I'm looking for the most optimal way to fetch data using useEffect()
when the fetch function is used in more than one place.
Situation
Currently, I have a parent component (ItemContainer
) and a child component (SearchBar
). ItemContainer
should fetch the all the possible list of items using getItemList()
functions. I'm executing this function within the useEffect()
during the first render, and also passing it down to SearchBar
component, so that when a user submits a search term, it will update itemList
state by triggering getItemList()
in ItemContainer
.
This actually works just as I expected. However, my issue is that
- I'm not really sure whether it is okay to define
getItemList()
outside theuseEffect()
in this kind of situation. From what I've been reading (blog posts, react official docs) it is generally recommended that data fetching function should be defined inside theuseEffect()
, although there could be some edge cases. I'm wondering if my case applies as this edge cases. - Is it okay to leave the dependency array empty in
useCallback
? I tried filling it out usingsearchTerm
,itemList
, but none of them worked - and I'm quite confused why this is so.
I feel bad that I don't fully understand the code that I wrote. I would appreciate if any of you could enlighten me with what I'm missing here...
ItemContainer
const ItemContainer = () => {
const [itemList, setItemList] = useState([]);
const getItemList = useCallback( async (searchTerm) => {
const itemListRes = await Api.getItems(searchTerm);
setItemList(itemListRes)
}, []);
useEffect(() => {
getItemList();
}, [getItemList]);
return (
<main>
<SearchBar search={getItemList} />
<ItemList itemList={itemList} />
</main>
)
}
SearchBar
const SearchBar = ({ search }) => {
const [searchTerm, setSearchTerm] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
search(searchTerm);
setSearchTerm('');
}
const handleChange = (e) => {
setSearchTerm(e.target.value)
}
return (
<form onSubmit={handleSubmit}>
<input
placeholder='Enter search term...'
value={searchTerm}
onChange={handleChange}
/>
<button>Search</button>
</form>
)
}