Skip to content
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

Possible to use React without a container element? #1970

Closed
nathansobo opened this issue Aug 1, 2014 · 5 comments
Closed

Possible to use React without a container element? #1970

nathansobo opened this issue Aug 1, 2014 · 5 comments

Comments

@nathansobo
Copy link

We're switching Atom to React, but we want to support backward-compatible shims to our previous view framework.

In the old framework, views were represented as jQuery-wrapped DOM elements. Ideally, we'd like to provide backward-compatible shims by simply rendering the React component and wrapping its root element in a jQuery wrapper with an API that's compatible to our old editor views. That would essentially look like this:

var editorRoot = document.createElement('div')
React.renderComponentWithRootElement(Editor(props), editorRoot)

// the element would actually be wrapped in a custom subclass of jQuery,
// but this is clearer for this example
var editorShim = $(editorRoot) 

Currently, this isn't possible because React components need to be rendered into a container. So instead we need to create a wrapper element and render the component inside it. This is sad because it adds an extra layer of markup which confuses styling, and also means that the editor has a wrapper when used via the shim layer but no wrapper when embedded as a child via React itself.

Is there something fundamental preventing React from adopting DOM nodes directly without the parent? Is this something we could even hack in in a way that would be somewhat maintainable?

❤️

@sophiebits
Copy link
Collaborator

It's a little tricky because (for example) what if Editor doesn't render a div but instead renders a span or some other tag? If editorRoot is in the DOM then React can do a replaceChild but if it's not you're out of luck. Maybe it just throws an error.

We are planning to do something similar though where you can render and call toElement in order to get a DOM node that you can put wherever you want: #1711. I'm guessing that would solve your problem? It requires some changes to the events system though so it's not likely to happen immediately. I'll close this issue in favor of that one but let me know if I'm missing something.

I don't think I can help get rid of the extra wrapper div but perhaps you could do it consistently if you render some EditorWrapper component when rendering from React but with the shim layer, render Editor inside a div you make. Sorry I don't have a better suggestion.

@syranide
Copy link
Contributor

syranide commented Aug 1, 2014

I'm curious, if we add the constraint that the root component must have a fixed root DOM component type and that it must export its type as a static variable (yuck, but easy short-term solution). Then it seems like it should only require a few minor tweaks for you to get some temporary solution in-place until toElement comes around. I'm not super familiar with the affected code so I can't guarantee that it is that simple, but it should be.

Does that sound like an acceptable workaround?

@nathansobo
Copy link
Author

@spicyj I love everything about the proposed API. I think it will really streamline integration of React into more heterogenous environments and also make it easier to support packages written in different versions of React by allowing the parent component to integrate manually through the DOM.

@syranide I would be totally fine with that workaround. The only component we'd currently need it for is the editor, and that's always a div.

@nathansobo
Copy link
Author

And we don't even need synthetic event support. We currently bind everything manually.

dgreensp referenced this issue in facebookarchive/react-meteor Jun 3, 2015
This effectively removes the requirement of providing a fixed root
container for React.render to use!
@joallard
Copy link

Looking for this, calling toElement kinda defeats the purpose of using ReactDOM to replace a component in the tree on a on-needed basis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants