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

Support comment node as a mount point #9835

Merged
merged 1 commit into from
Jun 28, 2017

Conversation

sophiebits
Copy link
Collaborator

This means you don't need an extra wrapper div for each component root you need. Rendered stuff is inserted before the comment you pass in.

@sophiebits
Copy link
Collaborator Author

This was surprisingly a lot easier than expected. What do you think? cc @pieterv @sebmarkbage

@@ -347,34 +354,49 @@ var DOMRenderer = ReactFiberReconciler({
parentInstance: Instance | Container,
child: Instance | TextInstance,
): void {
parentInstance.appendChild(child);
if (parentInstance.nodeType === COMMENT_NODE) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the check I was worried about. I wonder if we should have a different set of helpers that only apply when parentInstance is Container, i.e. the parent host fiber is a HostRoot so that this check only needs to apply on the very top level.

This check probably isn't that slow but it is for every insertion and we want that to be super fast if we for example go through this path for optimized paths that creates DOM nodes from server rendered markup.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. Maybe it's not so bad since markup generators would likely use the appendInitialChild path instead and not this one.

Still, seems cleaner if the Container had its own helpers so that hosts don't need to have to build pattern matching into their data structures when we already have the HostRoot tag for that.

Copy link

@thysultan thysultan Jun 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's a hot path, could checking for a non-getter property help here?

parentInstance.insertData !== undefined

Copy link
Collaborator

@sebmarkbage sebmarkbage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's branch in commitWork based on if the parent host fiber is HostRoot instead. That will avoid the check in the host config so that we can use it in hot paths where the check isn't needed. It will also let us get rid of this awkwardness in the RN renderer: https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeFiberRenderer.js#L62-L70

@pieterv
Copy link
Member

pieterv commented Jun 2, 2017

Love the general API. Only additional thing i would want is to provide a way to remove some placeholder content on commit, your idea (from when we chatted offline) of having start and end comment nodes sounds good to me since it would allow multiple nodes which works well for my usecase.

I'm happy to do any work here to get this over the line so let me know if you want any help :)

@sebmarkbage
Copy link
Collaborator

We currently remove placeholder content inside a container before rendering. It's a bit awkward since with async the placeholder gets removed synchronously. I think to do that, we'd probably need to tie into the hydration code which will need to know whether we want to hydrate the existing content or always remove it.

sophiebits added a commit to sophiebits/react that referenced this pull request Jun 16, 2017
This makes it so you don't need to pattern-match manually to build a renderer where the container and instance types are not the same. Prerequisite to facebook#9835.
sophiebits added a commit to sophiebits/react that referenced this pull request Jun 16, 2017
This makes it so you don't need to pattern-match manually to build a renderer where the container and instance types are not the same. Prerequisite to facebook#9835.
sophiebits added a commit to sophiebits/react that referenced this pull request Jun 16, 2017
This makes it so you don't need to pattern-match manually to build a renderer where the container and instance types are not the same. Prerequisite to facebook#9835.
sophiebits added a commit to sophiebits/react that referenced this pull request Jun 16, 2017
This makes it so you don't need to pattern-match manually to build a renderer where the container and instance types are not the same. Prerequisite to facebook#9835.
sophiebits added a commit that referenced this pull request Jun 16, 2017
This makes it so you don't need to pattern-match manually to build a renderer where the container and instance types are not the same. Prerequisite to #9835.
@sophiebits sophiebits force-pushed the comment-mount-point branch 3 times, most recently from d0fa63a to d3186de Compare June 27, 2017 22:02
Copy link
Collaborator

@sebmarkbage sebmarkbage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might need a rebase on top of #10056

invariant(mountPoint.nodeType === 8, 'Expected comment');
});

it('renders', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better test description plz.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in a describe tho! Not my fault that it doesn't show up nicely in the file. (Okay, yes it is…)

This means you don't need an extra wrapper div for each component root you need. Rendered stuff is inserted before the comment you pass in.
@sophiebits sophiebits merged commit 864ae8f into facebook:master Jun 28, 2017
container.nodeType !== 1 ||
!container.tagName ||
container.tagName.toUpperCase() !== 'BODY',
container.nodeType !== ELEMENT_NODE ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for updating the node types to use constants.

'Aaeiou<!-- react-mount-point-unstable -->B',
);

ReactDOM.render(list('yea'), mountPoint);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have both this and the previous expectation? They seem to be testing the same thing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tests deletes and moves (that's why I used keys above).

@aickin
Copy link
Contributor

aickin commented Jun 28, 2017

This is really cool!

I'd feel a little better about it if the server render/hydration path was tested as well. What do you think about adding a render mode in ReactDOMServerIntegration-test.js that attempts to server render and mount to a comment node?

@sophiebits
Copy link
Collaborator Author

Good question. I wouldn't expect this to work server-side right now since we don't know where the React-owned nodes start. I need to look more at how things are set up in order to figure that out. (or if you want to. :))

@sophiebits
Copy link
Collaborator Author

Was sorta thinking you might have a comment before and after; then if you have a placeholder React can also handle removing that.

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

Successfully merging this pull request may close these issues.

None yet

7 participants