mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Fix Router navigation state handling
The changes improve state handling during client-side navigation by: - Using correct function updates with setAppState - Preserving abort controller on updates - Adding proper cache ID comparison - Moving router instance to constants
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
import { onServerSideReload } from "bun:app/client";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
import { initialRscPayloadThen } from "./client/app.ts";
|
||||
import { router } from "./client/constants.ts";
|
||||
import { Root } from "./client/root.tsx";
|
||||
import { Router } from "./client/router.ts";
|
||||
|
||||
const router = new Router();
|
||||
|
||||
hydrateRoot(document, <Root />, {
|
||||
onUncaughtError(e) {
|
||||
@@ -50,13 +48,8 @@ const firstPageId = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
// Client side navigation is implemented by updating the app's `useState` with a
|
||||
// new RSC payload promise. Callers of `navigate` are expected to manage history
|
||||
// state. A navigation id is used
|
||||
|
||||
window.addEventListener("popstate", async event => {
|
||||
const state = typeof event.state === "number" ? event.state : undefined;
|
||||
|
||||
await router.navigate(location.href, state);
|
||||
});
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ export class Router {
|
||||
|
||||
// Save this promise so that pressing the back button in the browser navigates
|
||||
// to the same instance of the old page, instead of re-fetching it.
|
||||
if (cacheId) {
|
||||
if (cacheId !== undefined) {
|
||||
this.cachedPages.set(cacheId, {
|
||||
css: [...this.css.getList()],
|
||||
element: p,
|
||||
@@ -124,21 +124,22 @@ export class Router {
|
||||
}
|
||||
|
||||
// Tell react about the new page promise
|
||||
if (document.startViewTransition as unknown) {
|
||||
if (document.startViewTransition) {
|
||||
document.startViewTransition(() => {
|
||||
flushSync(() => {
|
||||
if (thisNavigationId === this.lastNavigationId)
|
||||
setAppState({
|
||||
if (thisNavigationId === this.lastNavigationId) {
|
||||
setAppState(old => ({
|
||||
rsc: p,
|
||||
abortOnRender: olderController ?? undefined,
|
||||
});
|
||||
abortOnRender: olderController ?? old.abortOnRender,
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
setAppState({
|
||||
setAppState(old => ({
|
||||
rsc: p,
|
||||
abortOnRender: olderController ?? undefined,
|
||||
});
|
||||
abortOnRender: olderController ?? old.abortOnRender,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user