Skip to content

Instantly share code, notes, and snippets.

@elado
Created September 14, 2016 04:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elado/dc63f0936d77c7290dac8bf719752b66 to your computer and use it in GitHub Desktop.
Save elado/dc63f0936d77c7290dac8bf719752b66 to your computer and use it in GitHub Desktop.
MobX/Redux DevTools in root without an extra div

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
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment