-
Notifications
You must be signed in to change notification settings - Fork 47.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support rendering into comment #17547
Comments
Is there some particular use case for this feature? |
@vkurchatkin In my particular use case, I'm trying to port a design system so it could be used with different frameworks. I've created react wrapper components for my existing components written using lit-html. This feature is would allow me to use simulate slots and project component's children inside lit-html template: html`<div>Project here: ${slotDirective()}</div>` I've figured that the const el = React.createElement(React.Fragment, {}, props.children);
ReactDOM.render([el], theCommentNode); to render the children in that place. To be fair, React is not my strongest suit and I'm not much qualified to find other use cases. Perhaps this feature could also be used with portals to also avoid creating wrappers. |
You could use JS to create the nodes you need in the DOM. Here is a quick PoC of finding the specific text node, create a div and insert after it, then ReactDOM.render into that div. https://codesandbox.io/s/render-react-app-after-a-text-node-5hhkc <div>
<header>header</header>
<!-- render MyComponent here -->
<div class="react-app"></div> <--- div created by JS and React is mounted here
<footer>footer</footer>
</div> Maybe this could work? |
@kunukn Well that's what I want to avoid - creating wrapper divs. In the example you provided the actual DOM is: <div>
<header>header</header>
<!-- render MyComponent here -->
<div class="react-app"><!-- don't want this -->
<section>hello world</section>
</div>
<footer>footer</footer>
</div> Clearly you can see how that can be undesirable behavior. Not only it creates unnecessary element, but it can mess with layout and css. |
My best approach is some JS creativity. function App() {
return (
<>
{/* <section> is omitted */}
Hello world
{/* </section> is omitted */}
</>
);
}
bootstrapReactApp(
{ renderAtComment: "render MyComponent here", nodeType: "section" },
{ className: "app" },
App
); This generates the desired DOM structure. <div>
<header>header</header>
<!-- render MyComponent here -->
<section class="app">hello world</section>
<footer>footer</footer>
</div> Demo example using button and state here. |
@kunukn Thanks for the help, but what if there are multiple sections? I cannot make that assumption that there will be only one wrapping element. In fact, I can tell you for sure that I'm expecting cases when there could be more: <my-input>
<i class="icon-search" style="order: -1" />
<i class="icon-keyboard" />
<i class="icon-clear" />
</my-input> Which projected inside component should generate in DOM something like: <my-input>
<div class="label"></div>
<div class="container" style="display: flex">
<input />
<i class="icon-search" style="order: -1" />
<i class="icon-keyboard" />
<i class="icon-clear" />
</div>
</my-input> For example, lit-html can render template into |
The problem I see here is that React has to take over the container for all components and erase all non-React siblings. For an example, consider the following HTML. <div id="#react-container">
<div>completely unrelated to React</div>
</div> If If you really need this kind of behavior, I think you would have to invert the logic and put React at the top of your tree and |
@dawidgarus i think this is already supported, although not documented (probably because it is still marked as unstable). here is the PR that added support for this, you can see it was done long time ago and it works very similar to what you are requesting, the only difference is that the component rendering result is added before the comment node, not after, in any case i guess it does not matter for you. the other requirement for this feature to work is that the comment node is exactly the following: you can see a live example of that here hope it helps you. |
@bjrmatos Thanks, that's exactly what I need. Although, I'm not really comfortable with using undocumented APIs and magic constants like 'react-mount-point-unstable'. |
I believe we’re going to remove that api in the near future. We only use it inside fb, and we’re moving away from it. |
@threepointone That's unfortunate. There are some really cool use cases for this. |
Seems like this option has been removed with the addition of createRoot & hydrateRoot. Are there any other options to support rendering into a comment instead of a dom element? |
Do you want to request a feature or report a bug?
Feature
What is the current behavior?
Currently there's isn't any way that I'm aware of to render a component in the middle of element without creating a wrapper element.
For example, let's consider this pure html fragment:
You could create
DocumentFragment
, but after you insert it to the DOM callingrender
again will generate error:If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:
What is the expected behavior?
It would be nice to have on option to pass a
Comment
node torender
function (and similar functions). In such cases, the react elements should be rendered next to the comment, which will work as an anchor to for the rendered content.Calling:
would result in following DOM structure:
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16
The text was updated successfully, but these errors were encountered: