When approaching the useEffect hook in React and to be fair hooks in general, the first thing is to forget what you think you know because you will get confused and you'll try to include a square block in a circular hole. When approaching creating components in React you should probably already be thinking "reactively" if you're not already doing so. What it means and how does it fit within the useEffect hook as an example is something that many front-end developers already know and will find this completely obvious. On the other hand, it took me a while to understand the concept of a reactive component enough to be able to explain it to a grandma in one or two sentences. The moment you create a self-enclosed component with its own Axios API calls based on the props you pass to it feels really good. I could finally say "I get it" now. So here's the deal. For those of you who don't yet grasp the concepts, building your lego blocks in React can be done the ugly way - creating a standalone piece of code with a class component and an API call in the constructor, coming from an older version of Angular this was the concept I initially understood, - the
OnInit() function is being run when the component builds. That's great, it used to work fine with the older concepts, but that's not how it's done any more for a good while now and you may think you're doing it logically right when in fact that's not the way to go in React (nor is it Angular any more btw for a long while...).
Our good old friend ESLint will also suggest to include a reference to the function in the dependency array of our
useEffect(). When it comes to functions, what you need to know is if they are included within the main body of the functional component, on the next render their memory reference will change. This means that it will technically be a different
fetchMyDataStuff() function than the one you first rendered. This is why you might also get another ESLint suggestion to enclose your
fetchMyDataStuff() in a
useCallback effect. The documentation explains it with a very clear
callback. which for those of us who prefer plain English means that the enclosed function will be stored in memory, so that it doesn't change every time you re-render your component.
As Wikipedia explains: "In computing, memoization or memoisation is an optimisation technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again. Memoization has also been used in other contexts (and for purposes other than speed gains), such as in simple mutually recursive descent parsing. Although related to caching, memoization refers to a specific case of this optimisation, distinguishing it from forms of caching such as buffering or page replacement. In the context of some logic programming languages, memoization is also known as tabling.
Going by this logic, the useCallback function being memoised will not only prevent your linting errors from annoying you, but more importantly, it will cache your function and speed up your app's performance.
To conclude, when writing your app in React and building component, hooks or no hooks, try to think about it as a self-enclosed piece of logic which depends on the prop data you provide it AND what's more important here, asynchronously changes by reacting to the changes in the web app and re-renders itself and its content without the need for external handling. Otherwise things get out of hand very quickly.