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:
Kenny Smith 2017-09-27 12:09:16 -07:00 committed by Tim Neutkens
parent a50e440cf1
commit d19cc975f4
5 changed files with 21 additions and 24 deletions

View file

@ -123,9 +123,9 @@ export async function renderError (error) {
if (prod) {
const initProps = { err: error, pathname, query, asPath }
const props = await loadGetInitialProps(ErrorComponent, initProps)
ReactDOM.render(createElement(ErrorComponent, props), errorContainer)
ReactDOM.hydrate(createElement(ErrorComponent, props), errorContainer)
} 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
ReactDOM.unmountComponentAtNode(errorContainer)
ReactDOM.render(createElement(App, appProps), appContainer)
ReactDOM.hydrate(createElement(App, appProps), appContainer)
if (emitter) {
emitter.emit('after-reactdom-render', { Component, ErrorComponent })

View file

@ -1,5 +1,4 @@
import 'react-hot-loader/patch'
import ReactReconciler from 'react-dom/lib/ReactReconciler'
import initOnDemandEntries from './on-demand-entries-client'
import initWebpackHMR from './webpack-hot-middleware-client'
@ -35,17 +34,3 @@ next.default()
.catch((err) => {
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
}
}

View file

@ -5,6 +5,10 @@ import { warn } from './utils'
import { makePublicRouterInstance } from './router'
export default class App extends Component {
state = {
hasError: null
}
static childContextTypes = {
headManager: 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 () {
if (this.state.hasError) return null
const { Component, props, hash, router } = this.props
const url = createUrl(router)
// If there no component exported we can't proceed.

View file

@ -127,15 +127,15 @@
"node-notifier": "5.1.2",
"nyc": "11.2.1",
"portfinder": "1.0.13",
"react": "15.5.4",
"react-dom": "15.5.4",
"react": "16.0.0",
"react-dom": "16.0.0",
"standard": "9.0.2",
"taskr": "1.1.0",
"wd": "1.4.1"
},
"peerDependencies": {
"react": "^15.5.4",
"react-dom": "^15.5.4"
"react": "^16.0.0",
"react-dom": "^16.0.0"
},
"jest": {
"testEnvironment": "node",

View file

@ -11,7 +11,7 @@ export default function ({ app }, suiteName, render) {
describe(suiteName, () => {
test('renders a stateless component', async () => {
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()
})
@ -23,7 +23,7 @@ export default function ({ app }, suiteName, render) {
test('header helper renders header information', async () => {
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('I can haz meta tags')).toBeTruthy()
})