diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index f7a37e8e3263..c00d17f7276c 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -678,47 +678,38 @@ if (process.env.__NEXT_RSC) { } = require('next/dist/compiled/react-server-dom-webpack') const encoder = new TextEncoder() - const serverDataBuffer = new Map() - const serverDataWriter = new Map() - const serverDataCacheKey = getCacheKey() + let initialServerDataBuffer: string[] | undefined = undefined + let initialServerDataWriter: WritableStreamDefaultWriter | undefined = + undefined function nextServerDataCallback(seg: [number, string, string]) { - const key = serverDataCacheKey + ',' + seg[1] if (seg[0] === 0) { - serverDataBuffer.set(key, []) + initialServerDataBuffer = [] } else { - const buffer = serverDataBuffer.get(key) - if (!buffer) + if (!initialServerDataBuffer) throw new Error('Unexpected server data: missing bootstrap script.') - const writer = serverDataWriter.get(key) - if (writer) { - writer.write(encoder.encode(seg[2])) + if (initialServerDataWriter) { + initialServerDataWriter.write(encoder.encode(seg[2])) } else { - buffer.push(seg[2]) + initialServerDataBuffer.push(seg[2]) } } } - function nextServerDataRegisterWriter( - key: string, - writer: WritableStreamDefaultWriter - ) { - const buffer = serverDataBuffer.get(key) - if (buffer) { - buffer.forEach((val) => { + function nextServerDataRegisterWriter(writer: WritableStreamDefaultWriter) { + if (initialServerDataBuffer) { + initialServerDataBuffer.forEach((val) => { writer.write(encoder.encode(val)) }) } - serverDataWriter.set(key, writer) + initialServerDataWriter = writer } // When `DOMContentLoaded`, we can close all pending writers to finish hydration. document.addEventListener( 'DOMContentLoaded', function () { - serverDataWriter.forEach((writer) => { - if (!writer.closed) { - writer.close() - } - }) + if (initialServerDataWriter && !initialServerDataWriter.closed) { + initialServerDataWriter.close() + } }, false ) @@ -744,18 +735,14 @@ if (process.env.__NEXT_RSC) { } function useServerResponse(cacheKey: string, serialized?: string) { - const id = (React as any).useId() - let response = rscCache.get(cacheKey) if (response) return response - const bufferCacheKey = cacheKey + ',' + router.route + ',' + id - const hasKey = serverDataBuffer.has(bufferCacheKey) - if (hasKey) { + if (initialServerDataBuffer) { const t = new TransformStream() const writer = t.writable.getWriter() response = createFromFetch(Promise.resolve({ body: t.readable })) - nextServerDataRegisterWriter(bufferCacheKey, writer) + nextServerDataRegisterWriter(writer) } else { const fetchPromise = serialized ? (() => { @@ -784,6 +771,9 @@ if (process.env.__NEXT_RSC) { React.useEffect(() => { rscCache.delete(cacheKey) }) + React.useEffect(() => { + initialServerDataBuffer = undefined + }, []) const response = useServerResponse(cacheKey, serialized) const root = response.readRoot() return root @@ -794,7 +784,7 @@ if (process.env.__NEXT_RSC) { const { __flight_serialized__ } = props const [, dispatch] = useState({}) const startTransition = (React as any).startTransition - const renrender = () => dispatch({}) + const rerender = () => dispatch({}) // If there is no cache, or there is serialized data already function refreshCache(nextProps: any) { startTransition(() => { @@ -804,7 +794,7 @@ if (process.env.__NEXT_RSC) { ) rscCache.set(currentCacheKey, response) - renrender() + rerender() }) } diff --git a/test/integration/react-streaming-and-server-components/app/components/nav.server.js b/test/integration/react-streaming-and-server-components/app/components/nav.server.js new file mode 100644 index 000000000000..23fb83d933a3 --- /dev/null +++ b/test/integration/react-streaming-and-server-components/app/components/nav.server.js @@ -0,0 +1,23 @@ +import Link from 'next/link' + +export default function Nav() { + return ( + <> +
+ + next link + +
+
+ + streaming rsc + +
+
+ + home + +
+ + ) +} diff --git a/test/integration/react-streaming-and-server-components/app/pages/index.server.js b/test/integration/react-streaming-and-server-components/app/pages/index.server.js index 2ccb8a8fde27..4bbf05c55236 100644 --- a/test/integration/react-streaming-and-server-components/app/pages/index.server.js +++ b/test/integration/react-streaming-and-server-components/app/pages/index.server.js @@ -1,5 +1,5 @@ import Foo from '../components/foo.client' -import Link from 'next/link' +import Nav from '../components/nav.server' const envVar = process.env.ENV_VAR_TEST const headerKey = 'x-next-test-client' @@ -14,14 +14,7 @@ export default function Index({ header, router }) {
-
- - next link - -
- - refresh - +