1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Allow app component to be wrapped with custom enhancer when rendering (#4762)

* Add support for custom App and Component enhancers

* Add ctx.renderPage test

* Add tests for single enhancer function

* Cleanup renderPage options check

* Cleanup

* Add comment about backwards compatibility for renderPage

* Add more test cases
This commit is contained in:
Albin Ekblom 2018-07-13 11:22:45 +02:00 committed by Tim Neutkens
parent dca2ca6f2b
commit 992ea2e875
3 changed files with 62 additions and 8 deletions

View file

@ -81,12 +81,23 @@ async function doRender (req, res, pathname, query, {
// the response might be finshed on the getinitialprops call // the response might be finshed on the getinitialprops call
if (isResSent(res)) return if (isResSent(res)) return
const renderPage = (enhancer = Page => Page) => { const renderPage = (options = Page => Page) => {
const app = createElement(App, { let EnhancedApp = App
Component: enhancer(Component), let EnhancedComponent = Component
router,
...props // For backwards compatibility
}) if (typeof options === 'function') {
EnhancedComponent = options(Component)
} else if (typeof options === 'object') {
if (options.enhanceApp) {
EnhancedApp = options.enhanceApp(App)
}
if (options.enhanceComponent) {
EnhancedComponent = options.enhanceComponent(Component)
}
}
const app = createElement(EnhancedApp, { Component: EnhancedComponent, router, ...props })
const render = staticMarkup ? renderToStaticMarkup : renderToString const render = staticMarkup ? renderToStaticMarkup : renderToString

View file

@ -2,8 +2,26 @@ import Document, { Head, Main, NextScript } from 'next/document'
export default class MyDocument extends Document { export default class MyDocument extends Document {
static async getInitialProps (ctx) { static async getInitialProps (ctx) {
const initialProps = await Document.getInitialProps(ctx) let options
return { ...initialProps, customProperty: 'Hello Document' }
const enhanceComponent = Component => (props) => <div><span id='render-page-enhance-component'>RENDERED</span><Component {...props} /></div>
const enhanceApp = Component => (props) => <div><span id='render-page-enhance-app'>RENDERED</span><Component {...props} /></div>
if (ctx.query.withEnhancer) {
options = enhanceComponent
} else if (ctx.query.withEnhanceComponent || ctx.query.withEnhanceApp) {
options = {}
if (ctx.query.withEnhanceComponent) {
options.enhanceComponent = enhanceComponent
}
if (ctx.query.withEnhanceApp) {
options.enhanceApp = enhanceApp
}
}
const result = ctx.renderPage(options)
return { ...result, customProperty: 'Hello Document' }
} }
render () { render () {

View file

@ -34,6 +34,31 @@ export default function ({ app }, suiteName, render, fetch) {
}) })
expect(noncesAdded).toBe(true) expect(noncesAdded).toBe(true)
}) })
test('It renders ctx.renderPage with enhancer correctly', async () => {
const $ = await get$('/?withEnhancer=true')
const nonce = 'RENDERED'
expect($('#render-page-enhance-component').text().includes(nonce)).toBe(true)
})
test('It renders ctx.renderPage with enhanceComponent correctly', async () => {
const $ = await get$('/?withEnhanceComponent=true')
const nonce = 'RENDERED'
expect($('#render-page-enhance-component').text().includes(nonce)).toBe(true)
})
test('It renders ctx.renderPage with enhanceApp correctly', async () => {
const $ = await get$('/?withEnhanceApp=true')
const nonce = 'RENDERED'
expect($('#render-page-enhance-app').text().includes(nonce)).toBe(true)
})
test('It renders ctx.renderPage with enhanceApp and enhanceComponent correctly', async () => {
const $ = await get$('/?withEnhanceComponent=true&withEnhanceApp=true')
const nonce = 'RENDERED'
expect($('#render-page-enhance-app').text().includes(nonce)).toBe(true)
expect($('#render-page-enhance-component').text().includes(nonce)).toBe(true)
})
}) })
describe('_app', () => { describe('_app', () => {