Revert support for render prop in <Main /> (#32184)

Reverts support for render prop in `<Main />` in `Document`. This was added just to support the `useFlushEffect` hook, but we've tweaked the design a bit, moving it to `App`.
This commit is contained in:
Gerald Monaco 2021-12-06 13:22:05 -08:00 committed by GitHub
parent 1fe014ce17
commit 9bcf678e64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 11 additions and 121 deletions

View file

@ -756,15 +756,11 @@ export class Head extends Component<
}
}
export function Main({
children,
}: {
children?: (content: JSX.Element) => JSX.Element
}) {
const { docComponentsRendered, useMainContent } = useContext(HtmlContext)
const content = useMainContent(children)
export function Main() {
const { docComponentsRendered } = useContext(HtmlContext)
docComponentsRendered.Main = true
return content
// @ts-ignore
return <next-js-internal-body-render-target />
}
export class NextScript extends Component<OriginProps> {

View file

@ -1048,20 +1048,6 @@ export async function renderToHTML(
return inAmpMode ? children : <div id="__next">{children}</div>
}
const appWrappers: Array<(content: JSX.Element) => JSX.Element> = []
const getWrappedApp = (app: JSX.Element) => {
// Prevent wrappers from reading/writing props by rendering inside an
// opaque component. Wrappers should use context instead.
const InnerApp = () => app
return (
<AppContainerWithIsomorphicFiberStructure>
{appWrappers.reduceRight((innerContent, fn) => {
return fn(innerContent)
}, <InnerApp />)}
</AppContainerWithIsomorphicFiberStructure>
)
}
/**
* Rules of Static & Dynamic HTML:
*
@ -1106,13 +1092,13 @@ export async function renderToHTML(
const html = ReactDOMServer.renderToString(
<Body>
{getWrappedApp(
<AppContainerWithIsomorphicFiberStructure>
<EnhancedApp
Component={EnhancedComponent}
router={router}
{...props}
/>
)}
</AppContainerWithIsomorphicFiberStructure>
</Body>
)
return { html, head }
@ -1137,15 +1123,6 @@ export async function renderToHTML(
documentElement: (htmlProps: HtmlProps) => (
<Document {...htmlProps} {...docProps} />
),
useMainContent: (fn?: (content: JSX.Element) => JSX.Element) => {
if (fn) {
throw new Error(
'The `children` property is not supported by non-functional custom Document components'
)
}
// @ts-ignore
return <next-js-internal-body-render-target />
},
head: docProps.head,
headTags: await headTags(documentCtx),
styles: docProps.styles,
@ -1164,9 +1141,9 @@ export async function renderToHTML(
</Body>
) : (
<Body>
{getWrappedApp(
<AppContainerWithIsomorphicFiberStructure>
<App {...props} Component={Component} router={router} />
)}
</AppContainerWithIsomorphicFiberStructure>
</Body>
)
return process.browser
@ -1181,9 +1158,9 @@ export async function renderToHTML(
</Body>
) : (
<Body>
{getWrappedApp(
<AppContainerWithIsomorphicFiberStructure>
<App {...props} Component={Component} router={router} />
)}
</AppContainerWithIsomorphicFiberStructure>
</Body>
)
// for non-concurrent rendering we need to ensure App is rendered
@ -1196,13 +1173,6 @@ export async function renderToHTML(
return {
bodyResult,
documentElement: () => (Document as any)(),
useMainContent: (fn?: (_content: JSX.Element) => JSX.Element) => {
if (fn) {
appWrappers.push(fn)
}
// @ts-ignore
return <next-js-internal-body-render-target />
},
head,
headTags: [],
styles: jsxStyleRegistry.styles(),
@ -1243,7 +1213,7 @@ export async function renderToHTML(
locales,
runtimeConfig,
} = renderOpts
const htmlProps: any = {
const htmlProps: HtmlProps = {
__NEXT_DATA__: {
props, // The result of getInitialProps
page: pathname, // The rendered page
@ -1297,7 +1267,6 @@ export async function renderToHTML(
head: documentResult.head,
headTags: documentResult.headTags,
styles: documentResult.styles,
useMainContent: documentResult.useMainContent,
useMaybeDeferContent,
crossOrigin: renderOpts.crossOrigin,
optimizeCss: renderOpts.optimizeCss,

View file

@ -221,7 +221,6 @@ export type HtmlProps = {
styles?: React.ReactElement[] | React.ReactFragment
head?: Array<JSX.Element | null>
useMaybeDeferContent: MaybeDeferContentHook
useMainContent: (fn?: (content: JSX.Element) => JSX.Element) => JSX.Element
crossOrigin?: string
optimizeCss?: boolean
optimizeFonts?: boolean

View file

@ -1,3 +0,0 @@
import { createContext } from 'react'
export default createContext(null)

View file

@ -1,7 +0,0 @@
const withReact18 = require('../../react-18/test/with-react-18')
module.exports = withReact18({
experimental: {
concurrentFeatures: true,
},
})

View file

@ -1,12 +0,0 @@
{
"scripts": {
"next": "node -r ../test/require-hook.js ../../../../packages/next/dist/bin/next",
"dev": "yarn next dev",
"build": "yarn next build",
"start": "yarn next start"
},
"dependencies": {
"react": "*",
"react-dom": "*"
}
}

View file

@ -1,20 +0,0 @@
import { Html, Head, Main, NextScript } from 'next/document'
import Context from '../lib/context'
export default function Document() {
return (
<Html>
<Head />
<body>
<Main>
{(children) => (
<Context.Provider value="from render prop">
{children}
</Context.Provider>
)}
</Main>
<NextScript />
</body>
</Html>
)
}

View file

@ -1,7 +0,0 @@
import { useContext } from 'react'
import Context from '../lib/context'
export default function MainRenderProp() {
const value = useContext(Context)
return <span>{value}</span>
}

View file

@ -1,25 +0,0 @@
/* eslint-env jest */
import { join } from 'path'
import { findPort, launchApp, killApp, renderViaHTTP } from 'next-test-utils'
const nodeArgs = ['-r', join(__dirname, '../../react-18/test/require-hook.js')]
const appDir = join(__dirname, '../app')
let appPort
let app
describe('Functional Custom Document', () => {
describe('development mode', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort, { nodeArgs })
})
afterAll(() => killApp(app))
it('supports render props', async () => {
const html = await renderViaHTTP(appPort, '/')
expect(html).toMatch(/<span>from render prop<\/span>/)
})
})
})