useFetch hook

  • code improvements
  • hooks


The process of creating a useFetch hook to handle asynchronous operations sprinkled with a dose of real-life examples.

Fetching and processing data from an API is one of the most repetitive activities in web applications.
That's why it's a good idea to make sure that the code you write is readable, consistent and easy to understand for others.
Don't count on developers. Everyone has different habits. It will be much easier to create an abstraction and encapsulate repetitive logic inside.
So let's jump into
hook creation process and see how it behaves in a real example.
1. What do you implement?
It will be a small app for loading users from a free API. You will be able to load users and display their avatars. Also, there will be an option to perform requests for details.
In addition, when the request is still pending you will be able to cancel the operation to save some browser resources after clicking
2. Looking at spaghetti
It works indeed, but the used approach is dirty like a mug.
Try to multiply it by the number of requests in the application or add another code - I wish you luck.
Generally, you can hide this logic in something like
- but implementation inside will be the same.
In addition - it's only users fetch logic. Still, we need to do the same for user details.
Problems with this code:
Imagine the whole application written like that 😺.
3. Can you do better?
Of course... Just look at the code below and try to understand it. I think it's obvious what is happening immediately.
Look at if statements. Inside
hook we implement later
exhaustiveness checking
. It will be discussed soon but in simple words - it prevents us from accessing properties when they aren't available and guide us by hand when writing conditional instructions.
All benefits:
4. Understanding exhaustiveness checking
You must have seen the difference in code and complexity that we discussed earlier. Now you need to understand how to implement this mechanism in
It is simple - just create several types that have a common property and make the union of them.
Right now you are not able to access properties other than
statement. This protects you from potential bugs and prevents you from adding code in the "other" style.
5. Abort controller
Before we start implementation there is one more thing to explain -
This class must be created one per request. Created instance exposes
property and
must be passed to
When you pass the signal property, then you can cancel the request via
function. You can do it at any time - depends on your needs.
In our case, we call
all time when the
function is executed.
Also it's good to cancel:
When a request is aborted you can see it in the console and network tab.
All of this will be possible by the usage of your
6. Adding tests suites
Let's create
file and same file for tests. You will use
. You need to cover the following test scenarios with implementation.
Test implementation is skipped. If you are interested - you can check it in this
or in the example at the end.
7. Implementing useFetch
Firstly, let's start with interfaces.
Next, we need to create a hook and implement a handler function with a state management transition which includes the option to abort a request.
Nothing fancy in this code. You just make generic everything that we discussed before.
8. Create renderer
We can also improve rendering. Instead of several
statements - you can create a component for handling that.
It simplifies rendering. Now it will be the same in the whole application.
9. Implementing our small app
Let's create two hooks that wrap logic for loading users and user details. These hooks will use your newly created
Now in
we can use
Right now it's time for the final step. Just use created hooks in the component and display dedicated UI.
Full example
to check the full solution or play with it on
I hope you enjoyed this quick win 🙂.
Together we explored a pretty interesting topic of creating abstractions in your code base and dealing with unneeded requests. Right now you can boost your work a little bit.
Feel free to contact me if you have any questions/proposals. Have a nice day and good health!