Skip to content

Allow Portals to be used for Reparenting #13044

Open
@philipp-spiess

Description

@philipp-spiess

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

feature

What is the current behavior?

Reparenting is an unsolved issues of React(DOM). So far, it was possible to hack around the missing support for it by relying on unstable API (unstable_renderSubtreeIntoContainer) to render and update a subtree inside a different container. It's important to note that this API was using React's diffing algorithm so that, similar to ReactDOM.render(), it is possible to keep components mounted.

ReactDOM.render(<Foo />, container);
// This won't get <Foo /> to be unmounted and mounted again:
ReactDOM.render(<Foo />, container);

ReactDOM.unstable_renderSubtreeIntoContainer(
  parentComponent,
  <Foo />,
  container
);
// This also won't get <Foo /> to be unmounted and mounted again, no matter if 
// we change parentComponent (and thus call it from a different parent):
ReactDOM.unstable_renderSubtreeIntoContainer(
  parentComponent,
  <Foo />,
  container
);

However this unstable API is going to be deprecated soon and recent features like the introduction of the new context API introduced additional issues.

As an alternative to this unstable API, ReactDOM.createPortal(children, container) was introduced. However this API is unsuitable for the reparenting issue since it will always create a new mount point inside the container instead of applying the diffing when called from a different parent (Check out this CodeSandbox where calling the portal from a different portal will cause the <Leaf /> to have a new uuid). The reason for this is that we want multiple portals to be able to render inside the same container which makes perfect sense for more common use cases like popovers, etc.

Before we're going to remove unstable_renderSubtreeIntoContainer, I suggest we find a way to portal into a specific node instead of appending to it so that we can diff its contents instead (or implement a solution for #3965 although that seems to be more complicated), similar to unstable_renderSubtreeIntoContainer.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions