Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

471
Views
Data Fetching Using useEffect() And useCallback In React

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

  1. I'm not really sure whether it is okay to define getItemList() outside the useEffect() 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 the useEffect(), although there could be some edge cases. I'm wondering if my case applies as this edge cases.
  2. Is it okay to leave the dependency array empty in useCallback? I tried filling it out using searchTerm, 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>
    )
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Here are my answers.

  1. Yes, it is okay. What's inside useCallback is "frozen" respect to the many ItemConteiner function calls that may happen. Since the useCallback content accesses only setItemList, which is also a frozen handler, there'll be no problems.

  2. That's also correct, because an empty array means "dependent to nothing". In other words, the callback is created once and keeps frozen for all the life of the ItemContainer.

Instead, this is something weird:

    useEffect(() => {
        getItemList();
    }, [getItemList]);

It works, but it has a very little sense. The getItemList is created once only, so why make an useEffect depending to something never changes?

Make it simpler, by running once only:

    useEffect(() => {
        getItemList();
    }, []);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!