diff --git a/packages/react-server/src/entry/browser.tsx b/packages/react-server/src/entry/browser.tsx index 803363f31..7677b6b96 100644 --- a/packages/react-server/src/entry/browser.tsx +++ b/packages/react-server/src/entry/browser.tsx @@ -1,4 +1,4 @@ -import { createDebug, memoize } from "@hiogawa/utils"; +import { createDebug } from "@hiogawa/utils"; import React from "react"; import ReactDOMClient from "react-dom/client"; import { @@ -36,7 +36,7 @@ export async function start() { const history = createEncodedBrowserHistory(); const router = new Router(history); - let $__setLayout: (v: Promise) => void; + let $__setLayout: (v: ServerRouterData) => void; let $__startActionTransition: React.TransitionStartFunction; // @@ -58,7 +58,7 @@ export async function start() { fetch(request), { callServer }, ); - $__startActionTransition(() => $__setLayout(result)); + $__startActionTransition(async () => $__setLayout(await result)); return (await result).action?.data; }; @@ -72,7 +72,6 @@ export async function start() { readStreamScript().pipeThrough(new TextEncoderStream()), { callServer }, ); - const initialLayoutPromise = Promise.resolve(initialLayout); // // browser root @@ -80,23 +79,18 @@ export async function start() { function LayoutHandler(props: React.PropsWithChildren) { const [layoutPromise, setLayoutPromise] = - React.useState>(initialLayoutPromise); - - // very shaky trick to merge with current layout - $__setLayout = (nextPromise) => { - setLayoutPromise( - memoize(async (currentPromise: Promise) => { - const current = await currentPromise; - const next = await nextPromise; - return { - action: next.action, - layout: { - ...current.layout, - ...next.layout, - }, - } satisfies ServerRouterData; - }), - ); + React.useState(initialLayout); + + $__setLayout = (next) => { + setLayoutPromise((current) => { + return { + action: next.action, + layout: { + ...current.layout, + ...next.layout, + }, + } satisfies ServerRouterData; + }); }; const [isPending, startTransition] = React.useTransition(); @@ -135,9 +129,9 @@ export async function start() { revalidate: ROUTER_REVALIDATE_KEY in location.state, }), ); - startTransition(() => { + startTransition(async () => { $__setLayout( - ReactClient.createFromFetch(fetch(request), { + await ReactClient.createFromFetch(fetch(request), { callServer, }), ); diff --git a/packages/react-server/src/entry/server.tsx b/packages/react-server/src/entry/server.tsx index 87fafc3ee..97c58dd68 100644 --- a/packages/react-server/src/entry/server.tsx +++ b/packages/react-server/src/entry/server.tsx @@ -85,15 +85,13 @@ export async function renderHtml( const [stream1, stream2] = result.stream.tee(); - const layoutPromise = ReactClient.createFromReadableStream( - stream1, - { + const serverData = + await ReactClient.createFromReadableStream(stream1, { ssrManifest: { moduleMap: createModuleMap(), moduleLoading: null, }, - }, - ); + }); const url = new URL(request.url); const history = createMemoryHistory({ @@ -105,7 +103,7 @@ export async function renderHtml( const reactRootEl = ( - + diff --git a/packages/react-server/src/features/router/client.tsx b/packages/react-server/src/features/router/client.tsx index 6ef8ac9b8..86404e5b5 100644 --- a/packages/react-server/src/features/router/client.tsx +++ b/packages/react-server/src/features/router/client.tsx @@ -10,7 +10,7 @@ import { import { LAYOUT_ROOT_NAME, type ServerRouterData } from "./utils"; type LayoutStateContextType = { - data: Promise; + data: ServerRouterData; }; export const LayoutStateContext = React.createContext( @@ -19,8 +19,7 @@ export const LayoutStateContext = React.createContext( export function LayoutContent(props: { name: string }) { const ctx = React.useContext(LayoutStateContext); - const data = React.use(ctx.data); - return data.layout[props.name]; + return ctx.data.layout[props.name]; } export function LayoutRoot() { diff --git a/packages/react-server/src/features/server-action/client.tsx b/packages/react-server/src/features/server-action/client.tsx index b7fc391d1..82647a9ed 100644 --- a/packages/react-server/src/features/server-action/client.tsx +++ b/packages/react-server/src/features/server-action/client.tsx @@ -14,9 +14,8 @@ export function ActionRedirectHandler() { // TODO: how to trigger nearest error page on action error? function ThrowActionError() { const ctx = React.useContext(LayoutStateContext); - const data = React.use(ctx.data); - if (data.action?.error) { - throw createError(data.action?.error); + if (ctx.data.action?.error) { + throw createError(ctx.data.action?.error); } return null; }