MobX/Redux's Provider
must get only a single child because it only renders what it gets, and React won't handle multiple objects returned from render
.
DevTools
are usually rendered at the top level component, but in case that top level component renders a router, it needs another element (e.g. div
) to wrap everything. This is not always wanted.
render() {
return (
<Provider {/* ... */}>
<div className="Root">
<Router {/* ... */}>
{routes}
</Router>
{__DEV__ && <DevTools />}
</div>
</Provider>
)
}
However, using a portal removes the need for the extra div
.
import React, { Component } from 'react'
import DevTools from 'mobx-react-devtools' // or redux or whatever
import { Provider } from 'mobx-react' // or redux or whatever
import ReactDOM, {
unstable_renderSubtreeIntoContainer as renderSubtreeIntoContainer,
unmountComponentAtNode
} from 'react-dom'
class App extends Component {
render() {
return (
<Provider {/* ... */}>
<Router {/* ... */}>
{routes}
</Router>
</Provider>
)
}
componentDidMount() {
if (!__DEV__) return
this._devToolsPortal = document.createElement('div')
document.body.appendChild(this._devToolsPortal)
renderSubtreeIntoContainer(this, <DevTools />, this._devToolsPortal)
}
componentWillUnmount() {
if (this._devToolsPortal) {
unmountComponentAtNode(this._devToolsPortal)
if (this._devToolsPortal.parentNode) {
this._devToolsPortal.parentNode.removeChild(this._devToolsPortal)
}
this._devToolsPortal = null
}
}
}