diff --git a/client/index.js b/client/index.js index 3c1fab58db77b..626fee5d0a806 100644 --- a/client/index.js +++ b/client/index.js @@ -5,6 +5,7 @@ import { rehydrate } from '../lib/css' import { createRouter } from '../lib/router' import App from '../lib/app' import evalScript from '../lib/eval-script' +import { loadGetInitialProps } from '../lib/utils' const { __NEXT_DATA__: { @@ -51,7 +52,7 @@ export async function render (props, onError = renderErrorComponent) { async function renderErrorComponent (err) { const { pathname, query } = router - const props = await getInitialProps(ErrorComponent, { err, pathname, query }) + const props = await loadGetInitialProps(ErrorComponent, { err, pathname, query }) await doRender({ Component: ErrorComponent, props, err }) } @@ -61,7 +62,7 @@ async function doRender ({ Component, props, err }) { lastAppProps.Component === ErrorComponent) { // fetch props if ErrorComponent was replaced with a page component by HMR const { pathname, query } = router - props = await getInitialProps(Component, { err, pathname, query }) + props = await loadGetInitialProps(Component, { err, pathname, query }) } Component = Component || lastAppProps.Component @@ -71,7 +72,3 @@ async function doRender ({ Component, props, err }) { lastAppProps = appProps ReactDOM.render(createElement(App, appProps), container) } - -function getInitialProps (Component, ctx) { - return Component.getInitialProps ? Component.getInitialProps(ctx) : {} -} diff --git a/examples/with-loading/pages/about.js b/examples/with-loading/pages/about.js index 5fd2ba798f779..a8f6029d6458d 100644 --- a/examples/with-loading/pages/about.js +++ b/examples/with-loading/pages/about.js @@ -3,10 +3,11 @@ import Header from '../components/Header' export default class About extends Component { // Add some delay - static getInitialProps () { - return new Promise((resolve) => { + static async getInitialProps () { + await new Promise((resolve) => { setTimeout(resolve, 500) }) + return {} } render () { diff --git a/examples/with-loading/pages/forever.js b/examples/with-loading/pages/forever.js index 5e4075fb504b2..be832b43cf595 100644 --- a/examples/with-loading/pages/forever.js +++ b/examples/with-loading/pages/forever.js @@ -3,10 +3,11 @@ import Header from '../components/Header' export default class Forever extends Component { // Add some delay - static getInitialProps () { - return new Promise((resolve) => { + static async getInitialProps () { + await new Promise((resolve) => { setTimeout(resolve, 3000) }) + return {} } render () { diff --git a/lib/router/router.js b/lib/router/router.js index 2569767ee02f9..a8f042e6bfb29 100644 --- a/lib/router/router.js +++ b/lib/router/router.js @@ -5,6 +5,7 @@ import evalScript from '../eval-script' import shallowEquals from '../shallow-equals' import { EventEmitter } from 'events' import { reloadIfPrefetched } from '../prefetch' +import { loadGetInitialProps } from '../utils' export default class Router extends EventEmitter { constructor (pathname, query, { Component, ErrorComponent, err } = {}) { @@ -234,7 +235,7 @@ export default class Router extends EventEmitter { const cancel = () => { cancelled = true } this.componentLoadCancel = cancel - const props = await (Component.getInitialProps ? Component.getInitialProps(ctx) : {}) + const props = await loadGetInitialProps(Component, ctx) if (cancel === this.componentLoadCancel) { this.componentLoadCancel = null diff --git a/lib/utils.js b/lib/utils.js index 7ffff02981e9e..56047419062a5 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -41,3 +41,15 @@ export function printAndExit (message, code = 1) { process.exit(code) } + +export async function loadGetInitialProps (Component, ctx) { + if (!Component.getInitialProps) return {} + + const props = await Component.getInitialProps(ctx) + if (!props) { + const compName = Component.displayName || Component.name + const message = `"${compName}.getInitialProps()" should resolve to an object. But found "${props}" instead.` + throw new Error(message) + } + return props +} diff --git a/server/render.js b/server/render.js index a9ea764833446..901b21b8b12b0 100644 --- a/server/render.js +++ b/server/render.js @@ -9,6 +9,7 @@ import requireModule from './require' import resolvePath from './resolve' import readPage from './read-page' import { Router } from '../lib/router' +import { loadGetInitialProps } from '../lib/utils' import Head, { defaultHead } from '../lib/head' import App from '../lib/app' @@ -52,7 +53,7 @@ async function doRender (req, res, pathname, query, { component, errorComponent ] = await Promise.all([ - Component.getInitialProps ? Component.getInitialProps(ctx) : {}, + loadGetInitialProps(Component, ctx), readPage(join(dir, '.next', 'bundles', 'pages', page)), readPage(join(dir, '.next', 'bundles', 'pages', '_error')) ]) @@ -80,7 +81,7 @@ async function doRender (req, res, pathname, query, { return { html, head } } - const docProps = await Document.getInitialProps({ ...ctx, renderPage }) + const docProps = await loadGetInitialProps(Document, { ...ctx, renderPage }) const doc = createElement(Document, { __NEXT_DATA__: { diff --git a/test/integration/basic/pages/empty-get-initial-props.js b/test/integration/basic/pages/empty-get-initial-props.js new file mode 100644 index 0000000000000..db9f9c036ed8f --- /dev/null +++ b/test/integration/basic/pages/empty-get-initial-props.js @@ -0,0 +1,4 @@ +const EmptyInitialPropsPage = () => (
This is the about page.
diff --git a/test/integration/basic/pages/nav/index.js b/test/integration/basic/pages/nav/index.js index 29e9ae3c35886..45f76488a2c8f 100644 --- a/test/integration/basic/pages/nav/index.js +++ b/test/integration/basic/pages/nav/index.js @@ -3,6 +3,10 @@ import { Component } from 'react' let counter = 0 +const linkStyle = { + marginRight: 10 +} + export default class extends Component { increase () { @@ -13,7 +17,8 @@ export default class extends Component { render () { return (This is the home.