Patterns for Doing API Calls in ReactJS
JM Santos
Posted on September 21, 2020
There are a lot of approaches we can make to do an API call in React. I will share what Iโve learned and discovered after dealing with different types of making an API call in React. This includes executions through hooks and without hooks.
Iโm also here to try and rethink the approaches that we always have but we tend to forget because of the new things. How well do we know the fundamentals?
Without further ado, letโs get started!
๐จโ๐ป Designing our Hooks
Before we get started with the different patterns, letโs start designing how our hooks will look like and also discuss why it was structured that way. I will start by creating a specialized API hook to fetch a list of todos.
We structured our hook this way in order to be flexible in different scenarios. The different scenarios will be discussed as we go through the list. I want to say that there are still unknowns and this isnโt perfect, but this is progress.
I know you will be having a lot of questions, here are some I can answer right now on this section, and letโs see if you can get an answer as we go through. If you donโt get an answer, letโs discuss it in another section.
- Why do we have two functions re-exported? One is the getTodos and another one is the useGetTodos
The reason we did that is to allow the consumerโโโthe one who will be using our hook, to have the ability to execute the API in a โhook wayโ version or in a โnon-hook wayโ version.
The idea here is that, to be able to reuse the same API core logic across the app. This is helpful when you are dealing with SSR with Next.js or Gatsby or also if you donโt need states into it.
- Should the logic be avoided in the hook implementation?
As much as possible we should avoid some logic on the hook that may alter the behavior of the API call. Letโs say you add some data transformers. Itโs better to add that in the non-hook version so that you have one place for it. In that way, we can add test coverage and all consumers regardless if using the hook and non-hook version will benefit from it.
- What is the use of the return value from the hook if the execute method returns the data already?
There are scenarios where you need the data immediately on the handler function (i.e onSubmit handler) for extra processing instead of relying on useEffect. Both are important, but as much as possible if we can do it on the handler function, do it there instead of listening through the useEffect for changes and react to it.
If the process depends on each other like the 2nd API call needs the result of the 1st API call, itโs hard to โchainโ those process together through useEffect.
Those are the questions I can answer now. I hope some of it gives you a better idea of it. Letโs get started now for the different patterns we will be learning together!
๐ก API Call on Component Mount
Scenario: When the user hits the page, we want to hit an API call on the component mount.
Intentionally didnโt wrap the hook in useEffect because we want to let the consumer decides when to run and how to run. I think that is important to consider. With this approach, we always control the execution and itโs pure. When I say pure, it means we know when and how it is run without going through our hook implementation itself. Which means it is easy to track when it fires off.
Demo:
https://medium.com/media/87873c79a7799615f15191b12c8d77f6/href
๐ก API Call on User Event (i.e. onClick, Form Submission)
Scenario: When the user submits the form, we want to do an API call to save the form.
https://medium.com/media/c04fb850afee92cc8c91450e4c922bf6/hrefhttps://medium.com/media/4afef3c2a7a316f7e979066e9bbaf0e8/href
The pattern for doing a POST API call is similar also with how we did the GET API call. They both have the hook and non-hook version exposed so that the consumer has the option to choose between the two on which is appropriate.
Also, the important thing on this hook implementation, if you will observe our execute method, it returns the data or it throws an error when there is. The return of data is important because there are scenarios where you need the response immediately instead of using a useEffect. You will see more about this when we go on running API calls in a serialized modeโโโwhere one response is needed to the next API call.
Demo:
https://medium.com/media/1e52ba8b8a690b4e95d03ece2840db4f/href
๐ก API Call on Search Field (autocomplete, table search)
Scenario: When the user types on a search field, we want to do an API call using the value that the user entered.
https://medium.com/media/2c0052ddfb2f6c4c0b3f2ba788ee1d54/hrefhttps://medium.com/media/1e8d707498df22643060aee00572d6a8/href
Demo:
https://medium.com/media/3743b2d9636d9b53383002fed4d96d3b/href
๐ก API Call on Paginate (with a limit)
Scenario: When the user selects a new page on the table, we want to do an API call to get the data on the selected page with the given limit. This can be applied also with other pagination options such as offset or sorting.
https://medium.com/media/b3eb220d2bec9d7def1143be619b5978/hrefhttps://medium.com/media/98252e84b195d37f50a759f08b27b94d/href
Demo:
https://medium.com/media/c8deb19f25ed84702b8728b547c628f3/href
๐ก API Call on Serialize Requests (2nd API call based on the 1st API call)
Scenario: When the user submits the form, we want to do multiple API calls in a serialize mode to process the form values.
https://medium.com/media/47fc0fce81021870ef2f412a7f3d24d8/href
The alternative of this is using the useEffect pattern, but I think it is incorrect to do that when the request is coming from a user event. What do I mean with that? Let me show you how it will look like on useEffect .
https://medium.com/media/4632d6c4d32c3c5f2d71ef41f56952da/href
When we do the useEffect approach, we need to add an extra flag state to teach our useEffect how it will react intellectually because if not, it will run infinite times. The inconvenience also on this approach is the resetting of the state value which will probably be tedious as the app grows big.
Hereโs another example:
https://medium.com/media/f3a5508d8b5af0e84c8ea2c39fdbe89b/href
Itโs hard to track states, understand the flow or sequence and the error handling is hard. To handle errors using this approach, you have to listen to the error object on each hook and put it inside the useEffect. This is also prone to infinite re-render. Prone to multiple API requests if not handled correctly. One incorrect flag and then there you go sending multiple API requests.
You might ask, why did I just put everything in one hook? Thatโs a good question. That will actually work and that is much better than with all these useEffect . That approach is like putting a lot inside of things into a single plastic. Weโre mixing a lot of things and putting a lot of responsibility to that hook. It will be hard to test it and make sure it is doing what it is supposed to do so. Itโs hard to reason that. Another reason why I didnโt do that is I want the API hooks to be used interdependently with each other. For example, I want to use API hook A to this page but I donโt want to fire API hook B. Itโs hard to do composition at a bigger level when all of those operations are inside a single hook.
Demo:
https://medium.com/media/4a67d83a3564ae917e6677f5d5aa4916/href
๐ค Bringing It All Together
There are a lot of use-cases Iโm not yet aware of and so this list canโt provide all of the examples but I think this provides good progress and pattern on how you will work on your API calls on React.
If you will observe most of the examples, it doesnโt have a lot of useEffect implementations. The reason is, I did encounter a lot of infinite loops already, implemented a lot through it, and got to the point where I realized that there are other options out there. Other options that existed way before this comes up. That option was the non-hook approach. Itโs always been there. But, we did substitute it with these new approaches.
I wonder if how many approaches can we solve with the basic approaches? Iโm not saying one is good and one is bad. I donโt know a lot to say that one is good and one is bad. Iโm trying to see if do I/we really have the right understanding of the fundamentals?
At the end of the day, this isnโt a silver bullet guide on how to perfectly do your API call on React but this will help you strategize or have another option on how to do it in another approach. Try it out and let me hear your experience with it!
Did I miss something? Comment down and letโs work on that!
Thank you for reading. I hope this will help you on your journey! โค๏ธ
Posted on September 21, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 18, 2024