Skip to content

Components with children without DOM representation #2191

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

Closed
freiksenet opened this issue Sep 14, 2014 · 14 comments
Closed

Components with children without DOM representation #2191

freiksenet opened this issue Sep 14, 2014 · 14 comments

Comments

@freiksenet
Copy link

If I need a component that doesn't have a DOM representation, I can use render function that returns <noscript>. However recently I had to have a component without DOM representation, but that also has children, that I want to be mounted (so that their lifecycle methods trigger correctly). Unfortunately <noscript> is not nestable, thus I had to return <span>, which is not an ideal solution.

Is there a way to do such thing without using <span> or <div>? I know there are plans to replace <noscript> solution with some 'null component'. Are there plans for 'null component' that can mount its children?

@andreypopp
Copy link
Contributor

This was discussed (see #690 (comment) for example) and I think it is/was on React's roadmap.

@freiksenet
Copy link
Author

Sounds great, thank you!

@syranide
Copy link
Contributor

If I need a component that doesn't have a DOM representation, I can use render function that returns <noscript>.

You can return null and it will (internally) translate to <noscript> for now.

However recently I had to have a component without DOM representation, but that also has children, that I want to be mounted (so that their lifecycle methods trigger correctly).

I'm not sure if I really undersand you. Composite classes (your own classes) by definition doesn't have a DOM representation, only React.DOM.* has. What you're asking for it seems is the ability to return multiple components from render(), see #2127. It's likely going to happen sometime in the future, but as you might hint from reading my comment in that PR I'm not convinced that it's generally a good idea and your solution is probably to refactor/rethink instead.

@freiksenet
Copy link
Author

I want to be able to return something that would work in a similar way to 'return null / noscript' (so practically no DOM representation), but would accept children and mount them.

@syranide
Copy link
Contributor

@freiksenet What you're asking for should still be to return multiple components. If you genuinely don't want them to be mounted into the DOM then you're using React components too much like OOP, which is not a good idea. React is only concerned with "views".

@freiksenet
Copy link
Author

I am making a library that are using react components as nodes in scenegraph canvas renderer https://github.com/freiksenet/react-kinetic. For scenegraph nodes that can have children, I want to return this children somehow from render, so they are mounted in react and their lifecycle methods trigger correctly, so that I can insert them into the scenegraph.

https://github.com/freiksenet/react-kinetic/blob/master/src/KineticContainerMixin.js

As you see currently I return null for terminal nodes, but I have to wrap children into spans.

@syranide
Copy link
Contributor

Ah yes, I see your point. But I don't think React (master branch) is well-suited to this at the moment, you can look at ReactART, it's a branch of React that works on SVG (or was it canvas) instead. Some dev probably has a more definitive answer for this.

@freiksenet
Copy link
Author

I have seen it and I have tried to model their approach at first. The problem is that it bases everything on ReactComponent, which lacks lots of features of ReactCompositeComponent that would be very nice to have, such as prop/context validation, context, lifecycle methods, lifecycle invariants. Unfortunately CompositeComponent doesn't separate all those parts very well and even the CompositeMixin is private and not exported.

@freiksenet
Copy link
Author

So yeah, the best solution would be to not do any hacks using DOM, but that requires composite component to be more decoupled from DOM and whose lifecycle and validation functionality is moved to mixins.

@freiksenet
Copy link
Author

I think @sebmarkbage 's work on decoupling mountComponent and other related methods might help with this issue.

@patrick-mcdougle
Copy link

Kinda new to react, but can you do this by using React.Children.only?

render() {
  return React.Children.only(this.props.children);
}

@qiaoyan
Copy link

qiaoyan commented Jul 24, 2017

测试测试

1 similar comment
@qiaoyan
Copy link

qiaoyan commented Jul 24, 2017

测试测试

@gaearon
Copy link
Collaborator

gaearon commented Oct 1, 2017

In React 16 you can both return null and arrays so there's no need for extra DOM nodes.

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

No branches or pull requests

6 participants