Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide AppTree to getInitialProps for getDataFromTree #7732

Merged
merged 26 commits into from
Jul 30, 2019
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8503348
Provide AppContainer to getInitialProps for getDataFromTree
ijjk Jul 2, 2019
e254fb5
Update to only pass AppTree component instead of AppContainer
ijjk Jul 2, 2019
ac2ce0a
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 2, 2019
2676eed
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 3, 2019
c1101dc
Clean up props and remove extra imports
ijjk Jul 3, 2019
02b2a05
Merge branch 'canary' into add/app-container
Timer Jul 3, 2019
b9b3f74
Make updates from review
ijjk Jul 3, 2019
eb716ac
Merge branch 'add/app-container' of github.com:ijjk/next.js into add/…
ijjk Jul 3, 2019
59b4983
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 3, 2019
ec18820
Merge branch 'canary' into add/app-container
Timer Jul 5, 2019
3693ca0
Merge branch 'canary' into add/app-container
Timer Jul 5, 2019
e40118b
Merge branch 'canary' into add/app-container
ijjk Jul 5, 2019
b92ebf3
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 15, 2019
d098767
Merge branch 'add/app-container' of github.com:ijjk/next.js into add/…
ijjk Jul 15, 2019
8bc3c62
Merge branch 'canary' into add/app-container
ijjk Jul 15, 2019
cb969ae
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 16, 2019
aa20ff7
Merge branch 'add/app-container' of github.com:ijjk/next.js into add/…
ijjk Jul 16, 2019
1100a59
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 16, 2019
ff415c4
De-dupe AppTree a bit
ijjk Jul 16, 2019
1f18aa2
Re-use wrapApp in router
ijjk Jul 23, 2019
5b7e256
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 23, 2019
76b2917
Remove un-needed change
ijjk Jul 23, 2019
be7ab89
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 26, 2019
8ab16db
Merge remote-tracking branch 'upstream/canary' into add/app-container
ijjk Jul 30, 2019
455d3d4
revert changes to examples until on stable
ijjk Jul 30, 2019
5223c8e
Add test for AppTree
ijjk Jul 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/next-server/lib/router/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export default class Router implements BaseRouter {
pageLoader: any
_bps: BeforePopStateCallback | undefined
events: MittEmitter
_wrapApp: (App: ComponentType) => any

static events: MittEmitter = mitt()

Expand All @@ -80,6 +81,7 @@ export default class Router implements BaseRouter {
initialProps,
pageLoader,
App,
wrapApp,
Component,
err,
subscription,
Expand All @@ -89,6 +91,7 @@ export default class Router implements BaseRouter {
pageLoader: any
Component: ComponentType
App: ComponentType
wrapApp: (App: ComponentType) => any
err?: Error
}
) {
Expand Down Expand Up @@ -117,6 +120,7 @@ export default class Router implements BaseRouter {
this.asPath = as
this.sub = subscription
this.clc = null
this._wrapApp = wrapApp

if (typeof window !== 'undefined') {
// in order for `e.state` to work on the `onpopstate` event
Expand Down Expand Up @@ -581,6 +585,7 @@ export default class Router implements BaseRouter {
const { Component: App } = this.components['/_app']

const props = await loadGetInitialProps<AppContextType<Router>>(App, {
AppTree: this._wrapApp(App),
Component,
router: this,
ctx,
Expand Down
3 changes: 2 additions & 1 deletion packages/next-server/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ export interface NextPageContext {

export type AppContextType<R extends NextRouter = NextRouter> = {
Component: NextComponentType<NextPageContext>
router: R
AppTree: NextComponentType
ctx: NextPageContext
router: R
}

export type AppInitialProps = {
Expand Down
39 changes: 24 additions & 15 deletions packages/next-server/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import Head, { defaultHead } from '../lib/head'
// @ts-ignore types will be added later as it's an internal module
import Loadable from '../lib/loadable'
import { DataManagerContext } from '../lib/data-manager-context'
import { RequestContext } from '../lib/request-context'
import { LoadableContext } from '../lib/loadable-context'
import { RouterContext } from '../lib/router-context'
import { DataManager } from '../lib/data-manager'
Expand Down Expand Up @@ -325,23 +324,33 @@ export async function renderToHTML(
const reactLoadableModules: string[] = []

const AppContainer = ({ children }: any) => (
<RequestContext.Provider value={req}>
<RouterContext.Provider value={router}>
<DataManagerContext.Provider value={dataManager}>
<AmpStateContext.Provider value={ampState}>
<LoadableContext.Provider
value={moduleName => reactLoadableModules.push(moduleName)}
>
{children}
</LoadableContext.Provider>
</AmpStateContext.Provider>
</DataManagerContext.Provider>
</RouterContext.Provider>
</RequestContext.Provider>
<RouterContext.Provider value={router}>
<DataManagerContext.Provider value={dataManager}>
<AmpStateContext.Provider value={ampState}>
<LoadableContext.Provider
value={moduleName => reactLoadableModules.push(moduleName)}
>
{children}
</LoadableContext.Provider>
</AmpStateContext.Provider>
</DataManagerContext.Provider>
</RouterContext.Provider>
)

try {
props = await loadGetInitialProps(App, { Component, router, ctx })
props = await loadGetInitialProps(App, {
Component,
AppTree: (props: any) => {
const appProps = { ...props, Component, router }
return (
<AppContainer>
<App {...appProps} />
</AppContainer>
)
},
router,
ctx,
})
} catch (err) {
if (!dev || !err) throw err
ctx.err = err
Expand Down
33 changes: 24 additions & 9 deletions packages/next/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export default async ({ webpackHMR: passedWebpackHMR } = {}) => {
pageLoader,
App,
Component,
wrapApp,
err: initialErr,
subscription: ({ Component, props, err }, App) => {
render({ App, Component, props, err, emitter })
Expand Down Expand Up @@ -211,13 +212,16 @@ export async function renderError (props) {
// In production we do a normal render with the `ErrorComponent` as component.
// If we've gotten here upon initial render, we can use the props from the server.
// Otherwise, we need to call `getInitialProps` on `App` before mounting.
const appCtx = {
AppTree: wrapApp(App),
Component: ErrorComponent,
router,
ctx: { err, pathname: page, query, asPath }
}

const initProps = props.props
? props.props
: await loadGetInitialProps(App, {
Component: ErrorComponent,
router,
ctx: { err, pathname: page, query, asPath }
})
: await loadGetInitialProps(App, appCtx)

await doRender({ ...props, err, Component: ErrorComponent, props: initProps })
}
Expand Down Expand Up @@ -256,6 +260,15 @@ function AppContainer ({ children }) {
)
}

const wrapApp = App => props => {
const appProps = { ...props, Component, err, router }
return (
<AppContainer>
<App {...appProps} />
</AppContainer>
)
}

async function doRender ({ App, Component, props, err }) {
// Usual getInitialProps fetching is handled in next/router
// this is for when ErrorComponent gets replaced by Component by HMR
Expand All @@ -266,17 +279,19 @@ async function doRender ({ App, Component, props, err }) {
lastAppProps.Component === ErrorComponent
) {
const { pathname, query, asPath } = router
props = await loadGetInitialProps(App, {
Component,
const appCtx = {
router,
AppTree: wrapApp(App),
Component: ErrorComponent,
ctx: { err, pathname, query, asPath }
})
}
props = await loadGetInitialProps(App, appCtx)
}

Component = Component || lastAppProps.Component
props = props || lastAppProps.props

const appProps = { Component, err, router, ...props }
const appProps = { ...props, Component, err, router }
// lastAppProps has to be set before ReactDom.render to account for ReactDom throwing an error.
lastAppProps = appProps

Expand Down
5 changes: 0 additions & 5 deletions packages/next/client/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import React from 'react'
import Router, { NextRouter } from 'next-server/dist/lib/router/router'
import { RouterContext } from 'next-server/dist/lib/router-context'
import { RequestContext } from 'next-server/dist/lib/request-context'

type ClassArguments<T> = T extends new (...args: infer U) => any ? U : any

Expand Down Expand Up @@ -118,10 +117,6 @@ export function useRouter() {
return React.useContext(RouterContext)
}

export function useRequest() {
return React.useContext(RequestContext)
}

// INTERNAL APIS
// -------------
// (do not use following exports inside the app)
Expand Down