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

Migrate next/router to use React.createContext (#6030)

Fixes parts of #5716. I had some issues with the test suite but I'm fairly certain that I got it working correctly.
This commit is contained in:
Alexander Nanberg 2019-01-11 16:04:56 +01:00 committed by Tim Neutkens
parent 68ceef68e1
commit 25fb3f9c2e
8 changed files with 42 additions and 33 deletions

View file

@ -1,10 +1,13 @@
/* global __NEXT_DATA__ */ /* global __NEXT_DATA__ */
import React from 'react'
import { parse, format } from 'url' import { parse, format } from 'url'
import mitt from '../mitt' import mitt from '../mitt'
import shallowEquals from './shallow-equals' import shallowEquals from './shallow-equals'
import { loadGetInitialProps, getURL } from '../utils' import { loadGetInitialProps, getURL } from '../utils'
export const RouterContext = React.createContext()
export default class Router { export default class Router {
static events = mitt() static events = mitt()

View file

@ -36,8 +36,8 @@
"url": "0.11.0" "url": "0.11.0"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^16.0.0", "react": "^16.3.0",
"react-dom": "^16.0.0" "react-dom": "^16.3.0"
}, },
"devDependencies": { "devDependencies": {
"@taskr/clear": "1.1.0", "@taskr/clear": "1.1.0",

View file

@ -2,7 +2,7 @@ import {IncomingMessage, ServerResponse} from 'http'
import { ParsedUrlQuery } from 'querystring' import { ParsedUrlQuery } from 'querystring'
import React from 'react' import React from 'react'
import { renderToString, renderToStaticMarkup } from 'react-dom/server' import { renderToString, renderToStaticMarkup } from 'react-dom/server'
import Router from '../lib/router/router' import Router, { RouterContext } from '../lib/router/router'
import { loadGetInitialProps, isResSent } from '../lib/utils' import { loadGetInitialProps, isResSent } from '../lib/utils'
import Head, { defaultHead } from '../lib/head' import Head, { defaultHead } from '../lib/head'
import Loadable from '../lib/loadable' import Loadable from '../lib/loadable'
@ -169,11 +169,13 @@ export async function renderToHTML (req: IncomingMessage, res: ServerResponse, p
return render(renderElementToString, return render(renderElementToString,
<LoadableCapture report={(moduleName) => reactLoadableModules.push(moduleName)}> <LoadableCapture report={(moduleName) => reactLoadableModules.push(moduleName)}>
<EnhancedApp <RouterContext.Provider value={router}>
Component={EnhancedComponent} <EnhancedApp
router={router} Component={EnhancedComponent}
{...props} router={router}
/> {...props}
/>
</RouterContext.Provider>
</LoadableCapture> </LoadableCapture>
) )
} }

View file

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import HeadManager from './head-manager' import HeadManager from './head-manager'
import { createRouter } from 'next/router' import { createRouter, makePublicRouterInstance, RouterContext } from 'next/router'
import mitt from 'next-server/dist/lib/mitt' import mitt from 'next-server/dist/lib/mitt'
import {loadGetInitialProps, getURL} from 'next-server/dist/lib/utils' import {loadGetInitialProps, getURL} from 'next-server/dist/lib/utils'
import PageLoader from './page-loader' import PageLoader from './page-loader'
@ -180,7 +180,9 @@ async function doRender ({ App, Component, props, err, emitter: emitterProp = em
// In development runtime errors are caught by react-error-overlay. // In development runtime errors are caught by react-error-overlay.
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
renderReactElement(( renderReactElement((
<App {...appProps} /> <RouterContext.Provider value={makePublicRouterInstance(router)}>
<App {...appProps} />
</RouterContext.Provider>
), appContainer) ), appContainer)
} else { } else {
// In production we catch runtime errors using componentDidCatch which will trigger renderError. // In production we catch runtime errors using componentDidCatch which will trigger renderError.
@ -193,7 +195,9 @@ async function doRender ({ App, Component, props, err, emitter: emitterProp = em
} }
renderReactElement(( renderReactElement((
<ErrorBoundary onError={onError}> <ErrorBoundary onError={onError}>
<App {...appProps} /> <RouterContext.Provider value={makePublicRouterInstance(router)}>
<App {...appProps} />
</RouterContext.Provider>
</ErrorBoundary> </ErrorBoundary>
), appContainer) ), appContainer)
} }

View file

@ -75,6 +75,9 @@ export default SingletonRouter
// Reexport the withRoute HOC // Reexport the withRoute HOC
export { default as withRouter } from './with-router' export { default as withRouter } from './with-router'
// Export RouterContext
export { RouterContext } from 'next-server/dist/lib/router/router'
// INTERNAL APIS // INTERNAL APIS
// ------------- // -------------
// (do not use following exports inside the app) // (do not use following exports inside the app)

View file

@ -1,25 +1,25 @@
import React, { Component } from 'react' import React from 'react'
import PropTypes from 'prop-types'
import hoistStatics from 'hoist-non-react-statics' import hoistStatics from 'hoist-non-react-statics'
import { getDisplayName } from 'next-server/dist/lib/utils' import { getDisplayName } from 'next-server/dist/lib/utils'
import { RouterContext } from './router'
export default function withRouter (ComposedComponent) { export default function withRouter (ComposedComponent) {
const displayName = getDisplayName(ComposedComponent) const displayName = getDisplayName(ComposedComponent)
class WithRouteWrapper extends Component { function WithRouteWrapper (props) {
static contextTypes = { return (
router: PropTypes.object <RouterContext.Consumer>
} {router => (
<ComposedComponent
static displayName = `withRouter(${displayName})` router={router}
{...props}
render () { />
return <ComposedComponent )}
router={this.context.router} </RouterContext.Consumer>
{...this.props} )
/>
}
} }
WithRouteWrapper.displayName = `withRouter(${displayName})`
return hoistStatics(WithRouteWrapper, ComposedComponent) return hoistStatics(WithRouteWrapper, ComposedComponent)
} }

View file

@ -95,8 +95,8 @@
"ws": "6.1.2" "ws": "6.1.2"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^16.0.0", "react": "^16.3.0",
"react-dom": "^16.0.0" "react-dom": "^16.3.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/parser": "7.2.0", "@babel/parser": "7.2.0",

View file

@ -1,12 +1,10 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { execOnce, loadGetInitialProps } from 'next-server/dist/lib/utils' import { execOnce, loadGetInitialProps } from 'next-server/dist/lib/utils'
import { makePublicRouterInstance } from 'next/router'
export default class App extends Component { export default class App extends Component {
static childContextTypes = { static childContextTypes = {
headManager: PropTypes.object, headManager: PropTypes.object
router: PropTypes.object
} }
static async getInitialProps ({ Component, router, ctx }) { static async getInitialProps ({ Component, router, ctx }) {
@ -17,8 +15,7 @@ export default class App extends Component {
getChildContext () { getChildContext () {
const { headManager } = this.props const { headManager } = this.props
return { return {
headManager, headManager
router: makePublicRouterInstance(this.props.router)
} }
} }