Skip to content

Commit

Permalink
Update tanstack router article
Browse files Browse the repository at this point in the history
  • Loading branch information
Swizec committed Jan 9, 2024
1 parent f79e8dc commit 220ba79
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 28 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1,12 +1,14 @@
---
title: "TanStack Router – modern React for the rest of us"
description: "TanStack Router puts the router in control of data, state, and UI and it's ... really good."
published: 2023-12-02
published: 2024-01-09
categories: "React, Suspense, Frontend, TanStack"
hero: ./img/screenshot-1701534305359.png
---

A few years ago Tanner created React Query with a simple pitch: GraphQL for the rest of us. All the affordances of Apollo GraphQL on top of your goode olde REST API. Everybody loved it. Now I think he's done it again with his TanStack Router.
_This article originally appeared on 2023-12-02 talking about a beta version of TanStack Router. It has been updated to reflect v1.1.12 as of 2024-01-09. You can [see the diff here]()_

A few years ago [Tanner](https://twitter.com/tannerlinsley) created React Query with a simple pitch: GraphQL for the rest of us. All the affordances of Apollo GraphQL on top of your goode olde REST API. Everybody loved it. Now I think he's done it again with his TanStack Router.

[TanStack Router](https://tanstack.com/router/v1) takes inspiration from Remix, NextJS, TRPC, and Chicane (first I heard of this one), combines the best parts and gives us:

Expand All @@ -18,7 +20,7 @@ A few years ago Tanner created React Query with a simple pitch: GraphQL for the

All this put together makes it possible to build next-gen apps with little effort and only a bit of rewiring how you think. No server-side rendering required 🤘

[![Example of nested routes with loading states](./img/Example-of-nested-routes-with-loading-states-g2hbhd.gif)](https://codesandbox.io/p/github/Swizec/tanstack-router-example/main?workspaceId=cfc721bc-f3ce-416f-8432-1e394cc3231b&file=%2Fsrc%2Fpages%2Fstory%2F%24id.tsx)
[![Example of nested routes with loading states](./img/Example-of-nested-routes-with-loading-states-hj5j25.gif)](https://swizec.com/blog/tanstack-router-modern-react-for-the-rest-of-us/)

## Why router-driven everything

Expand All @@ -41,15 +43,15 @@ Here's what a typical route in your app might look like:
```jsx
// src/pages/hello/reader.tsx

export const route = new FileRoute("/hello/reader").createRoute({
export const Route = new FileRoute("/hello/reader").createRoute({
component: SayHello,
loader: async () => fetchSomeData,
pendingComponent: LoadingState,
errorComponent: ErrorMessage,
})
});
```

This assumes you're using [file-based routing](https://tanstack.com/router/v1/docs/examples/react/file-based-routes) via the [router-cli utility](https://tanstack.com/router/v1/docs/api/router-cli). I've found that every React project eventually adapts a file structure similar to its URL structure. Might as well make it official.
This assumes you're using [file-based routing](https://tanstack.com/router/v1/docs/examples/react/quickstart-file-based) via the [router-cli utility](https://tanstack.com/router/v1/docs/api/router-cli). I've found that every React project eventually adapts a file structure similar to its URL structure. Might as well make it official.

The `component` renders when everything's okay and your data's ready. This is your core UI.

Expand All @@ -68,19 +70,21 @@ You control how that works with the `<Outlet />` component.
```jsx
// src/pages/__root.tsx

export const route = rootRoute({
component: () => {
return (
<Container>
<Header />
<Sidebar>
<Outlet />
</Sidebar>
<Footer />
</Container>
)
},
})
const RootComponent = () => {
return (
<Container>
<Header />
<Sidebar>
<Outlet />
</Sidebar>
<Footer />
</Container>
);
};

export const Route = rootRoute({
component: RootComponent,
});
```

The root component renders your app skeleton. `<Outlet />` is the part your subroutes control.
Expand All @@ -91,15 +95,15 @@ This route supports all the same loaders and pending states as other routes. You

Here's a small example so you can see what I'm talking about. Using timeouts instead of API calls to keep it simple.

https://codesandbox.io/p/github/Swizec/tanstack-router-example/main?workspaceId=cfc721bc-f3ce-416f-8432-1e394cc3231b\&file=%2Fsrc%2Fpages%2Fstory%2F%24id.tsx
https://codesandbox.io/p/github/Swizec/tanstack-router-example/main

In practice you’d wrap those slow API calls with a caching layer like React Query. And unlike my example, you’d actually use the data returned from your loaders. The official docs [have a good example for that](https://tanstack.com/router/v1/docs/examples/react/deferred-data?file=src%2Fmain.tsx)
TanStack Router [provides basic caching](https://tanstack.com/router/v1/docs/guide/data-loading#to-router-cache-or-not-to-router-cache) out of the box, but you'll want to use a real caching layer like React Query for serious apps. The extra control you get over cache invalidation is worth the effort.

You can see how it all works in this video:

![Example of nested routes with loading states](./img/Example-of-nested-routes-with-loading-states-j3aib4.gif)
[![Example of nested routes with loading states](./img/Example-of-nested-routes-with-loading-states-hga568.gif)](https://swizec.com/blog/tanstack-router-modern-react-for-the-rest-of-us/)

On first load, we wait for the index route’s loading state. Click on a story and you see the nested loading state. Now reload the page on this new URL and both loaders coordinate to show 1 top-level loading state.
On first load, we wait for the index route’s loading state. Click on a story and you see the nested loading state. No loading state on subsequent navigation thanks to built-in caching. Now reload the page on the new URL and the loaders should coordinate to show 1 top-level loading state. But maybe not 🤔

Colors show how nested routes create a layout for each other.

Expand All @@ -109,15 +113,19 @@ Colors show how nested routes create a layout for each other.

## Sharp edges

TanStack Router is beta software and under _very_ active development. Little details keep changing and the docs aren't done yet.
I've been using TanStack Router for a few months now and it's been good. The pace of development during beta was hard to keep up with, but jumping from `beta.282` to `v1.1.12` was effortless. No changes required 💪

https://twitter.com/Swizec/status/1744441614192562408

Documentation has improved lots in recent weeks. I'd start with the intro articles to get a sense of what Tanner is going for then diving into the [wealth of examples](https://tanstack.com/router/v1/docs/examples/react/quickstart) for the details.

For example I had to manually change the auto-generated route tree in `routeTree.gen.ts` to show you nested routes. The CLI wires them up wrong. And I had to [report a bug](https://github.com/TanStack/router/issues/831) about the nested suspense boundaries because the example above works in beta.205 from last week, but not in beta.225 from today.
My biggest gripe right now is that Router CLI's prettier and VSCode's prettier get into fights around formatting long filenames. I should make a pull request.

Tanner ships 🤘
## Should you use Tanner's Router?

For now I’ve found the best source of knowledge is to skim the base docs then reverse engineering [the wealth of examples](https://tanstack.com/router/v1/docs/examples/react/quickstart). And try things! See what works for you.
Overall I'm happy with this choice. We shipped the initial project on time and showed that the URL-based approach will solve the problems we were hoping to solve.

For me, I like where TanStack Router is going and have started using it for a greenfield app that fits this approach perfectly.
The next few weeks/months will show how this scales to multiple engineers of varying skill running around the project. 🤞

Cheers,<br />
\~Swizec

0 comments on commit 220ba79

Please sign in to comment.