Skip to content

Commit

Permalink
Element: enable concurrent mode by implementing mount/unmount with cr…
Browse files Browse the repository at this point in the history
…eateRoot
  • Loading branch information
jsnajdr committed Dec 12, 2022
1 parent 7c4fe12 commit 19b4697
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 30 deletions.
1 change: 1 addition & 0 deletions packages/element/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { default as createInterpolateElement } from './create-interpolate-element';
export * from './react';
export * from './react-platform';
export * from './react-root';
export * from './utils';
export { default as Platform } from './platform';
export { default as renderToString } from './serialize';
Expand Down
31 changes: 1 addition & 30 deletions packages/element/src/react-platform.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
/**
* External dependencies
*/
import {
createPortal,
findDOMNode,
render,
hydrate,
unmountComponentAtNode,
} from 'react-dom';
import { createPortal, findDOMNode } from 'react-dom';

/**
* Creates a portal into which a component can be rendered.
Expand All @@ -26,26 +20,3 @@ export { createPortal };
* @param {import('./react').WPComponent} component Component's instance.
*/
export { findDOMNode };

/**
* Renders a given element into the target DOM node.
*
* @param {import('./react').WPElement} element Element to render.
* @param {HTMLElement} target DOM node into which element should be rendered.
*/
export { render };

/**
* Hydrates a given element into the target DOM node.
*
* @param {import('./react').WPElement} element Element to hydrate.
* @param {HTMLElement} target DOM node into which element should be hydrated.
*/
export { hydrate };

/**
* Removes any mounted element from the target DOM node.
*
* @param {Element} target DOM node in which element is to be removed
*/
export { unmountComponentAtNode };
49 changes: 49 additions & 0 deletions packages/element/src/react-root.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* External dependencies
*/
import { createRoot, hydrateRoot } from 'react-dom/client';

const mountedRoots = new WeakMap();

/**
* Renders a given element into the target DOM node.
*
* @param {import('./react').WPElement} element Element to render.
* @param {HTMLElement} target DOM node into which element should be rendered.
*/
export function render( element, target ) {
let root = mountedRoots.get( target );
if ( ! root ) {
root = createRoot( target );
mountedRoots.set( target, root );
}
root.render( element );
}

/**
* Hydrates a given element into the target DOM node.
*
* @param {import('./react').WPElement} element Element to hydrate.
* @param {HTMLElement} target DOM node into which element should be hydrated.
*/
export function hydrate( element, target ) {
let root = mountedRoots.get( target );
if ( ! root ) {
root = hydrateRoot( target, element );
mountedRoots.set( target, root );
} else {
root.render( element );
}
}
/**
* Removes any mounted element from the target DOM node.
*
* @param {Element} target DOM node in which element is to be removed
*/
export function unmountComponentAtNode( target ) {
const root = mountedRoots.get( target );
if ( root ) {
root.unmount();
mountedRoots.delete( target );
}
}

0 comments on commit 19b4697

Please sign in to comment.