Why React Router's new data APIs boost productivity

Daniel Weinmann - Dec 21 '23 - - Dev Community

We've been using Remix at Seasoned for about two years now. And we consistently found that our teams are more productive with it.

In the past year or so, we also worked on a big React Router SPA to leverage the new data APIs. And the impact was very similar: a huge improvement in our team's throughput!

In this article, I'll share why React Router made that happen. There are many other benefits to adopting loaders and actions in your SPA, like page speed and better UX. But I'll focus on developer productivity today.

Before using the new data APIs, about two-thirds of our time was dedicated to managing our data fetching/mutation state. There are two main reasons for that:

  1. When managing state at the component level, we need to check if the data was already fetched, render a pending UI if not, and render our component when the data is ready. A similar approach is necessary for dealing with errors. For every component.

  2. Whenever we mutate data, we need to manually invalidate any state that became stale due to the changes. It's very hard to remember which states to invalidate at each mutation, and most of our bugs had to do with someone forgetting to revalidate something. And because we didn't know which component invalidated which state after each mutation, it took us a long time to diagnose these issues.

These challenges are not solved by TanStack Query (FKA React Query), SWR, and most similar libraries. But React Router 6.4+ makes them disappear!

Here's how we solved them with React Router:

  1. When you use a loader, your component is only rendered after the data is fetched. So you don't have to worry about pending UI. In our app, we rely on a global pending UI for most interactions, and that's it. For dealing with errors, we rely on error elements and response-throwing to keep our component focused on the happy path.

  2. React Router revalidates all loaders on the current route after each action, so we don't have to do any state management for mutations. Zero.

By eliminating these two problems, we reduced the cognitive load of our devs by an order of magnitude, I believe. Having to think so much about our app's state was slowing us down. And if you're not taking advantage of the data APIs yet, I bet it's dragging you down too!

. . . . . . . . . . . . . . . . . . . . . . . . .