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...).


Did you know you can add many useEffects listeners to a single component? Did you know sometimes you have to add more than one if you want to tie in state changes together? A 'side-effect' as it's nicely called by the documentation is basically something that happens when the state of any of the items in the dependency array changes. You can throw in some props or state variables and (and this is important, because the eslint will keep annoying you) functions which are used in the effect. The change of a variable is pretty self-explanatory, it's pretty cool when you tie in a variable to an API call and it calls and updates everything for you automagically. This automagical way ties in to our Reactive way of coding. We observe changes and then do something when that change happens. It is quite a paradigm shift which can be seen increasingly in other languages, like Swift or Flutter or even good old Java with RxJava or RxJS in JavaScript.

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 Returns a memoized 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.[1] 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.[2]

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.

So components?

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.