src/utils - Add getRootFiberNodeFromDOM helper

To find root Fiber node from overall html document or a particular element.
Ideally, this should be called with the same container element used in ReactDom.render.
This commit is contained in:
2019-08-08 11:51:33 +05:30
parent f94f7c5409
commit 05489aad2c
2 changed files with 44 additions and 2 deletions
+8
View File
@@ -1,5 +1,13 @@
import * as React from "react"; import * as React from "react";
export interface FiberNodeDOMContainer extends Element {
_reactRootContainer: {
_internalRoot: {
current: FiberNode | null;
};
};
}
export type FiberNode = export type FiberNode =
| FiberNodeForComponentClass | FiberNodeForComponentClass
| FiberNodeForFunctionComponent | FiberNodeForFunctionComponent
+36 -2
View File
@@ -3,7 +3,8 @@ import {
FiberNode, FiberNode,
FiberNodeisHTMLLike, FiberNodeisHTMLLike,
FiberNodeForFunctionComponent, FiberNodeForFunctionComponent,
FiberNodeForComponentClass FiberNodeForComponentClass,
FiberNodeDOMContainer
} from "./mocked-types"; } from "./mocked-types";
function isNodeHtmlLike(node: FiberNode): node is FiberNodeisHTMLLike { function isNodeHtmlLike(node: FiberNode): node is FiberNodeisHTMLLike {
@@ -60,6 +61,38 @@ function isConstructorFunctionComponent(
return !isConstructorComponentClass(ctr); return !isConstructorComponentClass(ctr);
} }
function doesElementContainRootFiberNode(
element: Element
): element is FiberNodeDOMContainer {
return element.hasOwnProperty("_reactRootContainer");
}
/**
* Util to find root React Fiber node from html DOM tree.
* Returns null, if not found.SHould be called after ReactDOM.render is finished.
* @param startElement Starting DOM element to seach from.
* If not found, it checks inside its child nodes. Defaults to document.body
*/
function getRootFiberNodeFromDOM(startElement?: Element): FiberNode | null {
if (startElement === undefined) {
startElement = document.body;
}
if (doesElementContainRootFiberNode(startElement)) {
return startElement._reactRootContainer._internalRoot.current;
}
let returnFiberNode = null;
for (const childNode of startElement.children) {
returnFiberNode = getRootFiberNodeFromDOM(childNode);
if (returnFiberNode !== null) {
return returnFiberNode;
}
}
return returnFiberNode;
}
export { export {
isNodeHtmlLike, isNodeHtmlLike,
isNodeNotHtmlLike, isNodeNotHtmlLike,
@@ -67,5 +100,6 @@ export {
isNodeComponentClass, isNodeComponentClass,
isConstructorHtmlLike, isConstructorHtmlLike,
isConstructorComponentClass, isConstructorComponentClass,
isConstructorFunctionComponent isConstructorFunctionComponent,
getRootFiberNodeFromDOM
}; };