React: Fiber cannot render to DocumentFragment/ShadowRoot

Created on 2 Oct 2017  路  12Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?
bug

What is the current behavior?
React 15.x was able to render within a DocumentFragment/shadowRoot, not possible with Fiber anymore

DEMO

https://www.webpackbin.com/bins/-KvPFG7-HGfQ34IgUxQt

import React, {Component} from 'react'
import {render} from 'react-dom'


class MyComponent extends Component{
  render(){
    return <div>Hello From React !</div>
  }
}

class MyElement extends HTMLElement {
  static is = 'my-element'
  constructor(){
    super()
    const shadowRoot = this.attachShadow({mode:'open'})
    try {
      // this fails 
      render(<MyComponent/>, shadowRoot)
    } catch (e){
      console.error(e)
      shadowRoot.innerHTML = `
        <div style="color:red;">${e}</div>
        <div>see console log for stack trace</div>
       `
    }
  }
  connectedCallback(){
    console.log('MyElement mounted!')
  }
}

customElements.define(MyElement.is, MyElement)

related -> https://github.com/skatejs/renderer-react/issues/3

What is the expected behavior?
be able to render to shadow root like previous versions of React

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React 16
Chrome

Bug

Most helpful comment

With 16.1.0-beta, render into document fragment works for me! Thanks!

All 12 comments

Hi, I have determined the same issue a few days ago.

This might be related to

https://github.com/Wildhoney/Keo/issues/37

The second note describes a fix to this problem. The method is getRootHostContext(rootContainerInstance) in the ReactFiberReconciler. If you apply this fix in the source and recompile, you will get another warning which says

Warning: validateDOMNesting(...):

cannot appear as a child of <#document>.

This issue needs more investigation, but the application itself should work on shadow-dom.

Thanks,
Markus

Note: there are more places in the source where we compare to DOCUMENT_NODE. Should we compare to DOCUMENT_FRAGMENT_NODE for them too? Do you want to do an audit and check all these cases?

Fix looks good @gaearon ! thx for super fast response :)

Note: there are more places in the source where we compare to DOCUMENT_NODE. Should we compare to DOCUMENT_FRAGMENT_NODE for them too? Do you want to do an audit and check all these cases?

I think this check within getRootHostContext should be enough for WebComponents

maybe also adding addition test for <template/> tag ?

const template = document.createElement('template')
template.innerHTML = `<div>Render here</div>`

const templateInstance = template.content.cloneNode(true)
ReactDOM.render(React.createElement(HelloWorld), templateInstance);

Would you like to contribute to the fixture I added? You can send a PR against my fork branch. You know more about web components than I do :-)

Hi, the mentioned warning validateDOMNesting did only occur with the development bundle. I did forget to activate NODE_ENV = 'production'.

Which tags to cover in a test might be a discussion for a dedicated thread because not only the