mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
React 16 (fiber) (#2996)
* Updating React to v16.0.0 * Updating error handling from ReactReconciler to componentDidCatch * Using hydrate() instead of render() on client side. * React 16 is not making `charSet` lowercase but that is in spec.
This commit is contained in:
parent
a50e440cf1
commit
d19cc975f4
|
@ -123,9 +123,9 @@ export async function renderError (error) {
|
||||||
if (prod) {
|
if (prod) {
|
||||||
const initProps = { err: error, pathname, query, asPath }
|
const initProps = { err: error, pathname, query, asPath }
|
||||||
const props = await loadGetInitialProps(ErrorComponent, initProps)
|
const props = await loadGetInitialProps(ErrorComponent, initProps)
|
||||||
ReactDOM.render(createElement(ErrorComponent, props), errorContainer)
|
ReactDOM.hydrate(createElement(ErrorComponent, props), errorContainer)
|
||||||
} else {
|
} else {
|
||||||
ReactDOM.render(createElement(ErrorDebugComponent, { error }), errorContainer)
|
ReactDOM.hydrate(createElement(ErrorDebugComponent, { error }), errorContainer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ async function doRender ({ Component, props, hash, err, emitter }) {
|
||||||
|
|
||||||
// We need to clear any existing runtime error messages
|
// We need to clear any existing runtime error messages
|
||||||
ReactDOM.unmountComponentAtNode(errorContainer)
|
ReactDOM.unmountComponentAtNode(errorContainer)
|
||||||
ReactDOM.render(createElement(App, appProps), appContainer)
|
ReactDOM.hydrate(createElement(App, appProps), appContainer)
|
||||||
|
|
||||||
if (emitter) {
|
if (emitter) {
|
||||||
emitter.emit('after-reactdom-render', { Component, ErrorComponent })
|
emitter.emit('after-reactdom-render', { Component, ErrorComponent })
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'react-hot-loader/patch'
|
import 'react-hot-loader/patch'
|
||||||
import ReactReconciler from 'react-dom/lib/ReactReconciler'
|
|
||||||
import initOnDemandEntries from './on-demand-entries-client'
|
import initOnDemandEntries from './on-demand-entries-client'
|
||||||
import initWebpackHMR from './webpack-hot-middleware-client'
|
import initWebpackHMR from './webpack-hot-middleware-client'
|
||||||
|
|
||||||
|
@ -35,17 +34,3 @@ next.default()
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(`${err.message}\n${err.stack}`)
|
console.error(`${err.message}\n${err.stack}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
// This is a patch to catch most of the errors throw inside React components.
|
|
||||||
const originalMountComponent = ReactReconciler.mountComponent
|
|
||||||
ReactReconciler.mountComponent = function (...args) {
|
|
||||||
try {
|
|
||||||
return originalMountComponent(...args)
|
|
||||||
} catch (err) {
|
|
||||||
if (!err.abort) {
|
|
||||||
next.renderError(err)
|
|
||||||
err.abort = true
|
|
||||||
}
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
12
lib/app.js
12
lib/app.js
|
@ -5,6 +5,10 @@ import { warn } from './utils'
|
||||||
import { makePublicRouterInstance } from './router'
|
import { makePublicRouterInstance } from './router'
|
||||||
|
|
||||||
export default class App extends Component {
|
export default class App extends Component {
|
||||||
|
state = {
|
||||||
|
hasError: null
|
||||||
|
}
|
||||||
|
|
||||||
static childContextTypes = {
|
static childContextTypes = {
|
||||||
headManager: PropTypes.object,
|
headManager: PropTypes.object,
|
||||||
router: PropTypes.object
|
router: PropTypes.object
|
||||||
|
@ -18,7 +22,15 @@ export default class App extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidCatch (error, info) {
|
||||||
|
error.stack = `${error.stack}\n\n${info.componentStack}`
|
||||||
|
window.next.renderError(error)
|
||||||
|
this.setState({ hasError: true })
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
if (this.state.hasError) return null
|
||||||
|
|
||||||
const { Component, props, hash, router } = this.props
|
const { Component, props, hash, router } = this.props
|
||||||
const url = createUrl(router)
|
const url = createUrl(router)
|
||||||
// If there no component exported we can't proceed.
|
// If there no component exported we can't proceed.
|
||||||
|
|
|
@ -127,15 +127,15 @@
|
||||||
"node-notifier": "5.1.2",
|
"node-notifier": "5.1.2",
|
||||||
"nyc": "11.2.1",
|
"nyc": "11.2.1",
|
||||||
"portfinder": "1.0.13",
|
"portfinder": "1.0.13",
|
||||||
"react": "15.5.4",
|
"react": "16.0.0",
|
||||||
"react-dom": "15.5.4",
|
"react-dom": "16.0.0",
|
||||||
"standard": "9.0.2",
|
"standard": "9.0.2",
|
||||||
"taskr": "1.1.0",
|
"taskr": "1.1.0",
|
||||||
"wd": "1.4.1"
|
"wd": "1.4.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^15.5.4",
|
"react": "^16.0.0",
|
||||||
"react-dom": "^15.5.4"
|
"react-dom": "^16.0.0"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"testEnvironment": "node",
|
"testEnvironment": "node",
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default function ({ app }, suiteName, render) {
|
||||||
describe(suiteName, () => {
|
describe(suiteName, () => {
|
||||||
test('renders a stateless component', async () => {
|
test('renders a stateless component', async () => {
|
||||||
const html = await render('/stateless')
|
const html = await render('/stateless')
|
||||||
expect(html.includes('<meta charset="utf-8" class="next-head"/>')).toBeTruthy()
|
expect(html.includes('<meta charSet="utf-8" class="next-head"/>')).toBeTruthy()
|
||||||
expect(html.includes('My component!')).toBeTruthy()
|
expect(html.includes('My component!')).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export default function ({ app }, suiteName, render) {
|
||||||
|
|
||||||
test('header helper renders header information', async () => {
|
test('header helper renders header information', async () => {
|
||||||
const html = await (render('/head'))
|
const html = await (render('/head'))
|
||||||
expect(html.includes('<meta charset="iso-8859-5" class="next-head"/>')).toBeTruthy()
|
expect(html.includes('<meta charSet="iso-8859-5" class="next-head"/>')).toBeTruthy()
|
||||||
expect(html.includes('<meta content="my meta" class="next-head"/>')).toBeTruthy()
|
expect(html.includes('<meta content="my meta" class="next-head"/>')).toBeTruthy()
|
||||||
expect(html.includes('I can haz meta tags')).toBeTruthy()
|
expect(html.includes('I can haz meta tags')).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue