Saturday, September 2, 2023

Improved filter performance; implementing custom hooks with react-query made it easier

I finally got some time to do a little work on sportsmap.world, and used it to work on improving filter performance in the frontend.

Working with getting start times for all these sporting events displaying correctly in their local time zone is actually a little tricky; it gets harder when you consider how to filter by date.  Midnight on September 2 in Seattle is different from the start time of September 2 in Italy, when you consider all the times I'm working with are normalized to UTC.  I had previously been doing a calculation at filter time to determine if the local start time for an event fell within the date filter range; by moving that calculation to the initial query function, I was able to improve query performance in the frontend.  

(Not a super-complicated perf improvement, but as with all software tasks, it's just a matter of finding the time and getting in the right mental space to work on it.)

One thing I have warmed up to is using custom hooks in React, especially in conjunction with Tanstack's react-query library.  One of my setup tasks for this perf improvement was to refactor two similar backend queries into a single custom hook with input parameters.  By tying into react-query's existing hooks for data, isLoading, isError, etc., I've been able to greatly reduce my own usage of useEffect, which makes for cleaner components.

A great combination I used on a recent work project: OpenAPI to define backend APIs, openapi-typescript and openapi-typescript-fetch to turn the API into usable Typescript objects, react-query to do the querying and maintain loading state and show errors, and wrap it all up into a custom hook which can be re-used by multiple components.  A really clean solution, especially for projects where the frontend is stateless; that is, object state is the responsibility of the backend, which is an especially useful paradigm for microservice environments.