Skip to content

Commit 173d7f4

Browse files
committed
Update popstate section in transition docs
1 parent 23adab6 commit 173d7f4

File tree

1 file changed

+1
-35
lines changed

1 file changed

+1
-35
lines changed

docs/explanation/react-transitions.md

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -144,34 +144,7 @@ startTransition(async () => {
144144

145145
#### `popstate` navigations
146146

147-
Due to limitations in React itself, [`popstate`][popstate] navigations cannot be Transition-enabled. Any state updates during a `popstate` event are [automatically][popstate-sync-pr] [flushed][bsky-ricky-popstate] synchronously so that the browser can properly restore scroll position and form data.
148-
149-
However, the browser can only do this if the navigation is instant. If React Router needs to run loaders on a back navigation, the browser will not be able to restore scroll position or form data ([`<ScrollRestoration>`][scroll-restoration] can handle scroll position for you).
150-
151-
It is therefore not recommended to wrap `navigate(n)` navigations in `React.startTransition`
152-
unless you can manage your pending UI with local Transition state (`React.useTransition`).
153-
154-
```tsx
155-
// ❌ This won't work correctly
156-
startTransition(() => navigate(-1));
157-
```
158-
159-
If you _need_ programmatic back-navigations to be Transition-friendly in your app, you can introduce a small hack to prevent React from detecting the event and letting the Transition work as expected. React checks `window.event` to determine if the state updates are part of a `popstate` event, so if you clear that out in your own listener you can trick React into treating it like any other state update:
160-
161-
```tsx
162-
// Add this to the top of your browser entry file
163-
window.addEventListener(
164-
"popstate",
165-
() => {
166-
window.event = null;
167-
},
168-
{
169-
capture: true,
170-
},
171-
);
172-
```
173-
174-
<docs-warning>Please be aware this is a hack, has not been thoroughly tested, and may not continue to work if React changes their underlying implementation. We did get their [permission][ricky-bsky-event-hack] to mention it though 😉</docs-warning>
147+
There is currently a bug with optimistic states and `popstate`. If you need to read the current route during a back navigation, which cannot complete synchronously (e.g. Suspends on uncached data), you can set the optimistic state before navigating back or defer the optimistic update in a timer or microtask.
175148

176149
[react-18]: https://react.dev/blog/2022/03/29/react-v18
177150
[concurrent]: https://react.dev/blog/2022/03/29/react-v18#what-is-concurrent-react
@@ -183,13 +156,6 @@ window.addEventListener(
183156
[use-optimistic-blog]: https://react.dev/blog/2024/12/05/react-19#new-hook-optimistic-updates
184157
[use-optimistic]: https://react.dev/reference/react/useOptimistic
185158
[flush-sync]: https://react.dev/reference/react-dom/flushSync
186-
[dan-issue]: https://github.com/remix-run/remix/issues/5763
187-
[startTransition-pr]: https://github.com/remix-run/react-router/pull/10438
188159
[rr-6-13-0]: https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v6130
189160
[uses-transition-issue]: https://github.com/facebook/react/issues/26382
190161
[uses-transition-tweet]: https://x.com/rickhanlonii/status/1683636856808775682
191-
[bsky-ricky-popstate]: https://bsky.app/profile/ricky.fm/post/3m5ujj6tuks2e
192-
[popstate-sync-pr]: https://github.com/facebook/react/pull/26025
193-
[scroll-restoration]: ../api/components/ScrollRestoration
194-
[ricky-bsky-event-hack]: https://bsky.app/profile/ricky.fm/post/3m5wgqw3swc26
195-
[popstate]: https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event

0 commit comments

Comments
 (0)