You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/blog/tanstack-router-navigation-lifetimes.md
+5-2Lines changed: 5 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -110,7 +110,7 @@ The final publish arrow compresses two steps: the private lane selects a result,
110
110
111
111
### One Loader, Several Leases <!-- "lease" explainer -->
112
112
113
-
Both the *preload* lane and the *navigation* lane need `/account`'s data. But the `loader` is only invoked once.
113
+
Both the _preload_ lane and the _navigation_ lane need `/account`'s data. But the `loader` is only invoked once.
114
114
115
115
Sharing one invocation raises a question: when is it safe to abort? So the invocation is wrapped in a **flight**: a promise, its abort controller, and a lease count. Every consumer that needs it takes a **lease**.[^flights]
116
116
@@ -125,7 +125,7 @@ Acquiring a lease raises the count. Releasing one removes that consumer's claim
125
125
126
126
Preloads, pending routes, rendered routes, and cache entries all hold leases, and a lease can outlive the promise it covers: the claim is about the lifetime of the resource, not the delivery of a value.
127
127
128
-
That is why `/account` still reaches the cache. Clicking `/settings` releases the *navigation*'s lease, but the hover's *preload* lease is still there. The count never reaches zero, nothing is aborted, and the result is cached when it finally settles.
128
+
That is why `/account` still reaches the cache. Clicking `/settings` releases the _navigation_'s lease, but the hover's _preload_ lease is still there. The count never reaches zero, nothing is aborted, and the result is cached when it finally settles.
129
129
130
130
### The Navigation Was Replaced. Its Loader Kept Going. <!-- "transaction" explainer -->
131
131
@@ -141,6 +141,7 @@ The slot changes hands, so the `/account` lane may never publish. The flight it
141
141
Without the transaction, the `/account` lane can no longer publish its matches. It will stop at its next async boundary and release its leases. This in turn may abort the loader flights that have no other leases, but in our example the preload still holds a lease which means the flight continues.
142
142
143
143
It becomes very easy to enforce that a lane cannot publish if it is not allowed to:
144
+
144
145
```ts
145
146
if (router._tx!==tx) {
146
147
finishPending(tx)
@@ -150,6 +151,7 @@ if (router._tx !== tx) {
150
151
```
151
152
152
153
<!-- TODO: this paragraph below is interesting, but it feels less about "transactions" (this section) than about lanes (section below) or leases (section above). -->
154
+
153
155
Notice what was never shared. The preload and the navigation each did their own matching, built their own context, ran their own `beforeLoad`, and kept their own lane. They shared one loader invocation and its outcome, nothing more. Reusing work must not mean inheriting another consumer's draft of the page.
154
156
155
157
### The Error Finished First. The Redirect Still Won. <!-- "lane" explainer -->
@@ -166,6 +168,7 @@ Loader outcomes return to the lane. The lane, not the order the promises settled
166
168
</figure>
167
169
168
170
<!-- TODO: the rest of this section is very confusing. We're saying simple things here, it feels like this shouldn't be this hard to explain it. -->
171
+
169
172
An ordinary failure is held as provisional, because other parallel loaders may still redirect. A redirect is control flow, not something to render: it asks for another navigation. So the redirect replaces the provisional failure, even though the error settled first.
170
173
171
174
This is not a general ranking where redirects matter more than errors. With no redirect in the branch, the lane still has to select a failure and the boundary that renders it. Our goal is merely that promise timing alone does not decide what reaches the page.
0 commit comments