From 25fb3f9c2e7a16c3eb363f9a4552c14bceb95767 Mon Sep 17 00:00:00 2001 From: Alexander Nanberg Date: Fri, 11 Jan 2019 16:04:56 +0100 Subject: [PATCH] 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. --- packages/next-server/lib/router/router.js | 3 +++ packages/next-server/package.json | 4 +-- packages/next-server/server/render.tsx | 14 ++++++----- packages/next/client/index.js | 10 +++++--- packages/next/client/router.js | 3 +++ packages/next/client/with-router.js | 30 +++++++++++------------ packages/next/package.json | 4 +-- packages/next/pages/_app.js | 7 ++---- 8 files changed, 42 insertions(+), 33 deletions(-) diff --git a/packages/next-server/lib/router/router.js b/packages/next-server/lib/router/router.js index ca200c5f..d4f4c1d5 100644 --- a/packages/next-server/lib/router/router.js +++ b/packages/next-server/lib/router/router.js @@ -1,10 +1,13 @@ /* global __NEXT_DATA__ */ +import React from 'react' import { parse, format } from 'url' import mitt from '../mitt' import shallowEquals from './shallow-equals' import { loadGetInitialProps, getURL } from '../utils' +export const RouterContext = React.createContext() + export default class Router { static events = mitt() diff --git a/packages/next-server/package.json b/packages/next-server/package.json index 0741501f..acd41ca9 100644 --- a/packages/next-server/package.json +++ b/packages/next-server/package.json @@ -36,8 +36,8 @@ "url": "0.11.0" }, "peerDependencies": { - "react": "^16.0.0", - "react-dom": "^16.0.0" + "react": "^16.3.0", + "react-dom": "^16.3.0" }, "devDependencies": { "@taskr/clear": "1.1.0", diff --git a/packages/next-server/server/render.tsx b/packages/next-server/server/render.tsx index 744aa2eb..a59827b9 100644 --- a/packages/next-server/server/render.tsx +++ b/packages/next-server/server/render.tsx @@ -2,7 +2,7 @@ import {IncomingMessage, ServerResponse} from 'http' import { ParsedUrlQuery } from 'querystring' import React from 'react' 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 Head, { defaultHead } from '../lib/head' import Loadable from '../lib/loadable' @@ -169,11 +169,13 @@ export async function renderToHTML (req: IncomingMessage, res: ServerResponse, p return render(renderElementToString, reactLoadableModules.push(moduleName)}> - + + + ) } diff --git a/packages/next/client/index.js b/packages/next/client/index.js index 41f355fe..89b46275 100644 --- a/packages/next/client/index.js +++ b/packages/next/client/index.js @@ -1,7 +1,7 @@ import React from 'react' import ReactDOM from 'react-dom' 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 {loadGetInitialProps, getURL} from 'next-server/dist/lib/utils' 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. if (process.env.NODE_ENV === 'development') { renderReactElement(( - + + + ), appContainer) } else { // 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(( - + + + ), appContainer) } diff --git a/packages/next/client/router.js b/packages/next/client/router.js index 18c96ceb..462a50c4 100644 --- a/packages/next/client/router.js +++ b/packages/next/client/router.js @@ -75,6 +75,9 @@ export default SingletonRouter // Reexport the withRoute HOC export { default as withRouter } from './with-router' +// Export RouterContext +export { RouterContext } from 'next-server/dist/lib/router/router' + // INTERNAL APIS // ------------- // (do not use following exports inside the app) diff --git a/packages/next/client/with-router.js b/packages/next/client/with-router.js index 91544572..93ac8327 100644 --- a/packages/next/client/with-router.js +++ b/packages/next/client/with-router.js @@ -1,25 +1,25 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React from 'react' import hoistStatics from 'hoist-non-react-statics' import { getDisplayName } from 'next-server/dist/lib/utils' +import { RouterContext } from './router' export default function withRouter (ComposedComponent) { const displayName = getDisplayName(ComposedComponent) - class WithRouteWrapper extends Component { - static contextTypes = { - router: PropTypes.object - } - - static displayName = `withRouter(${displayName})` - - render () { - return - } + function WithRouteWrapper (props) { + return ( + + {router => ( + + )} + + ) } + WithRouteWrapper.displayName = `withRouter(${displayName})` + return hoistStatics(WithRouteWrapper, ComposedComponent) } diff --git a/packages/next/package.json b/packages/next/package.json index 79d6f329..2bfff277 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -95,8 +95,8 @@ "ws": "6.1.2" }, "peerDependencies": { - "react": "^16.0.0", - "react-dom": "^16.0.0" + "react": "^16.3.0", + "react-dom": "^16.3.0" }, "devDependencies": { "@babel/parser": "7.2.0", diff --git a/packages/next/pages/_app.js b/packages/next/pages/_app.js index 9ed64c4b..cd698d94 100644 --- a/packages/next/pages/_app.js +++ b/packages/next/pages/_app.js @@ -1,12 +1,10 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { execOnce, loadGetInitialProps } from 'next-server/dist/lib/utils' -import { makePublicRouterInstance } from 'next/router' export default class App extends Component { static childContextTypes = { - headManager: PropTypes.object, - router: PropTypes.object + headManager: PropTypes.object } static async getInitialProps ({ Component, router, ctx }) { @@ -17,8 +15,7 @@ export default class App extends Component { getChildContext () { const { headManager } = this.props return { - headManager, - router: makePublicRouterInstance(this.props.router) + headManager } }