From 144aea80f74409832b10465ae0fa7d92d17bb148 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 9 May 2022 12:34:29 -0500 Subject: [PATCH 1/5] Update root component handling --- packages/next/server/view-render.tsx | 67 ++++++++++--------- test/e2e/views-dir/app/views/layout.server.js | 12 +++- test/e2e/views-dir/index.test.ts | 6 ++ 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/packages/next/server/view-render.tsx b/packages/next/server/view-render.tsx index f304f2472ce66..b3ff5d756ac59 100644 --- a/packages/next/server/view-render.tsx +++ b/packages/next/server/view-render.tsx @@ -19,7 +19,6 @@ import { import { FlushEffectsContext } from '../shared/lib/flush-effects' import { isDynamicRoute } from '../shared/lib/router/utils' import { tryGetPreviewData } from './api-utils/node' -import DefaultRootLayout from '../lib/views-layout' const ReactDOMServer = process.env.__NEXT_REACT_ROOT ? require('react-dom/server.browser') @@ -218,6 +217,8 @@ export async function renderToHTML( const isFlight = query.__flight__ !== undefined const flightRouterPath = isFlight ? query.__flight_router_path__ : undefined + delete query.__flight__ + delete query.__flight_router_path__ const hasConcurrentFeatures = !!runtime const pageIsDynamic = isDynamicRoute(pathname) @@ -247,22 +248,12 @@ export async function renderToHTML( (renderOpts as any).previewProps ) const isPreview = previewData !== false - - let WrappedComponent: any - let RootLayout: any - const dataCache = new Map() + let WrappedComponent: any for (let i = components.length - 1; i >= 0; i--) { const dataCacheKey = i.toString() const layout = components[i] - - if (i === 0) { - // top-most layout is the root layout that renders - // the html/body tags - RootLayout = layout.Component - continue - } let fetcher: any // TODO: pass a shared cache from previous getStaticProps/ @@ -313,8 +304,7 @@ export async function renderToHTML( // eslint-disable-next-line no-loop-func const lastComponent = WrappedComponent - WrappedComponent = () => { - let props: any + WrappedComponent = (props: any) => { if (fetcher) { // The data fetching was kicked off before rendering (see above) // if the data was not resolved yet the layout rendering will be suspended @@ -325,7 +315,25 @@ export async function renderToHTML( ) // Result of calling getStaticProps or getServerSideProps. If promise is not resolve yet it will suspend. const recordValue = readRecordValue(record) - props = recordValue.props + + if (props) { + props = Object.assign({}, props, recordValue.props) + } else { + props = recordValue.props + } + } + + // if this is the root layout pass children as bodyChildren prop + if (i === 0) { + return React.createElement(layout.Component, { + ...props, + headChildren: props.headChildren, + bodyChildren: React.createElement( + lastComponent || React.Fragment, + {}, + null + ), + }) } return React.createElement( @@ -345,11 +353,6 @@ export async function renderToHTML( // } } - // Fall back to default root layout that renders / / - if (!RootLayout) { - RootLayout = DefaultRootLayout - } - const headChildren = buildManifest.rootMainFiles.map((src) => (