At the start of this year, the team of ReactJS presented a fresh way to handle state and other library features – hooks. The developer’s community loved the idea from its very beginning when the feature was still in RFC state.
With the fall of the Redux and rise of the GraphQL, the react-apollo became one of the most popular approaches to data layer management. That doesn’t surprise me, just look at this elegant adoption of the hooks API for querying:
The useQuery here is the hook exported from the apollo library, it takes GraphQL query schema defined using the graphql-tag, and as a result, it returns an object that represents the state of the request. Neat, huh?
Sure, it most likely doesn’t make any sense for projects that were started a few years ago to get rewritten using some modern sexy tech, but developers’ experience still can be improved gradually step by step.
Real-world refactoring example
Last week I was added as a cross-project code reviewer to a project that uses classic REST + fetch-from-a-component data layer model. They have this API service which abstracts `fetch` calls using axios for its interceptors for auth tokens handling and more. Let’s take a look at a simplified version of container components that are responsible for request data from server:
The first thing that catches your eye, is the try/catch/finally code repetition. Also, the PostForm handles loading and error states for both requests, which logically should not be a component’s responsibility, moreover, it has the same loading and error property for different requests.
Basically, our GET and PUT requests are Queries and Mutations respectively in GraphQL, so the idea is to use apollo-style useQuery and useMutation hooks to have loading and error states of data fetching abstracted. Let’s make a draft of the end result we want to achieve:
Looks pretty! Now we can go ahead and write the hooks code:
The code for usePut is bit different – we don’t use the useEffect, but rather returning request function to the user:
Now our PostForm component will have the following shape:
We ended up moving the fetch state responsibility out of the PostForm component to hooks which we now can reuse and test in isolation. I love it!
In this article, we’ve covered an example of how to make a small step to upgrade a legacy codebase in order to improve code scalability and quality in accordance with the fresh tech stack standards.
p.s. Subscribe to Syndicode newsletter to get all the interesting news right to your mailbox!
Or just hire a professional team of Ruby/Rails developers who are always aware of the latest trends and know how to use all the latest tools!