Skip to content

Commit

Permalink
Fix missing _app component of AppTree in gIP context (#36206)
Browse files Browse the repository at this point in the history
## Bug

The custom app is missing in the `ctx.AppTree` that causing the issue, it was accidently missed in custom _app.server pr #35666

Fixes #36198

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`
  • Loading branch information
huozhi committed Apr 16, 2022
1 parent 9c7311b commit fe6e74d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 15 deletions.
17 changes: 11 additions & 6 deletions packages/next/server/render.tsx
Expand Up @@ -202,12 +202,17 @@ function renderFlight(AppMod: any, ComponentMod: any, props: any) {
const AppServer = isServerComponent
? (App as React.ComponentType)
: React.Fragment
const { router: _, ...rest } = props

return (
<AppServer>
<Component {...props} />
</AppServer>
)
if (isServerComponent) {
return (
<AppServer>
<Component {...rest} />
</AppServer>
)
}

return <App Component={Component} {...props} />
}

export type RenderOptsPartial = {
Expand Down Expand Up @@ -734,7 +739,7 @@ export async function renderToHTML(
AppTree: (props: any) => {
return (
<AppContainerWithIsomorphicFiberStructure>
{renderFlight(AppMod, ComponentMod, props)}
{renderFlight(AppMod, ComponentMod, { ...props, router })}
</AppContainerWithIsomorphicFiberStructure>
)
},
Expand Down
26 changes: 17 additions & 9 deletions test/integration/app-tree/pages/_app.tsx
@@ -1,9 +1,12 @@
import React from 'react'
import Link from 'next/link'
import { createContext } from 'react'
import { render } from 'react-dom'
import App, { AppContext } from 'next/app'
import { renderToString } from 'react-dom/server'

export const DummyContext = createContext(null)

class MyApp<P = {}> extends App<P & { html: string }> {
static async getInitialProps({ Component, AppTree, ctx }: AppContext) {
let pageProps = {}
Expand Down Expand Up @@ -32,15 +35,20 @@ class MyApp<P = {}> extends App<P & { html: string }> {
const { Component, pageProps, html, router } = this.props
const href = router.pathname === '/' ? '/another' : '/'

return html && router.pathname !== '/hello' ? (
<>
<div dangerouslySetInnerHTML={{ __html: html }} />
<Link href={href}>
<a id={href === '/' ? 'home' : 'another'}>to {href}</a>
</Link>
</>
) : (
<Component {...pageProps} />
const child =
html && router.pathname !== '/hello' ? (
<>
<div dangerouslySetInnerHTML={{ __html: html }} />
<Link href={href}>
<a id={href === '/' ? 'home' : 'another'}>to {href}</a>
</Link>
</>
) : (
<Component {...pageProps} />
)

return (
<DummyContext.Provider value={'::ctx::'}>{child}</DummyContext.Provider>
)
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/integration/app-tree/pages/index.js
@@ -1,7 +1,12 @@
import { useContext } from 'react'
import { DummyContext } from './_app'
import { useRouter } from 'next/router'

const Page = () => {
const { pathname } = useRouter()
const ctx = useContext(DummyContext)
if (ctx == null) throw new Error('context consumes failed')

return (
<>
<h3>page: {pathname}</h3>
Expand Down

0 comments on commit fe6e74d

Please sign in to comment.