The data about which component displayed what can be found breaking into the internal parts of the React instance, but you said that you want to take the DOM node and find out which React component displayed it, and this is a bit more complicated.
Do you really need to manipulate the DOM after React has reset it, or do you want to change the React element (which comes back from the JSX / React.createElement ) before rendering to the DOM? In any case, the capture intercept allows you to check the element and do what you need with it. Since child constituents do not expand to real DOM nodes until then, you only get the ones you need.
Here is an example decorator that will add a property to each element provided by this class:
function recursiveAddProps(elem, extraProps) { if (!elem) return; if (typeof elem === "string") { // strings get turned into spans return React.createElement("span", extraProps, elem); } const props = elem.props || {}; const newChildren = React.Children.map(props.children, child => recursiveAddProps(child, extraProps) ) return React.cloneElement(elem, extraProps, newChildren); } function DecoratorComponent(klass) { const oldRender = klass.prototype.render; klass.prototype.render = function() { const elem = oldRender.apply(this, arguments); const name = this.constructor.displayName || this.constructor.name; return recursiveAddProps(elem, { className: "myOverriddenClass" // this will set className on every element }); }; return klass; }
Using these components
class Foo extends React.Component { render() { return ( <div> <div>Hi!</div> <SomeOtherComponent /> {['a', 'b', 'c'].map(letter => <div>{letter}</div> )} </div> ); } } Foo = DecoratorComponent(Foo); class SomeOtherComponent extends React.Component { render() { return ( <ul> <li>Some</li> <li>Other</li> <li>Component</li> </ul> ); } }
the code leads to the DOM:
<div class="myOverriddenClass" data-reactid=".0"> <div class="myOverriddenClass" data-reactid=".0.$/=10"> <span class="myOverriddenClass" data-reactid=".0.$/=10.$/=10">Hi!</span> </div> <ul data-reactid=".0.$/=11"> <li data-reactid=".0.$/=11.0">Some</li> <li data-reactid=".0.$/=11.1">Other</li> <li data-reactid=".0.$/=11.2">Component</li> </ul> <div class="myOverriddenClass" data-reactid=".0.$/=12=20"> <span class="myOverriddenClass" data-reactid=".0.$/=12=20.$/=10">a</span> </div> <div class="myOverriddenClass" data-reactid=".0.$/=12=21"> <span class="myOverriddenClass" data-reactid=".0.$/=12=21.$/=10">b</span> </div> <div class="myOverriddenClass" data-reactid=".0.$/=12=22"> <span class="myOverriddenClass" data-reactid=".0.$/=12=22.$/=10">c</span> </div> </div>
You can see that a class has been added to each element, except for the ones that SomeOtherComponent displays - ul and li s.
If you want to set some special attribute on the DOM nodes so that you can determine if its Foo component is displayed, you can specify the data- attribute, and React will hide it until the DOM.
<div data-rendered-by="Foo" data-reactid=".0"> <div data-rendered-by="Foo" data-reactid=".0.$/=10"> <span data-rendered-by="Foo" data-reactid=".0.$/=10.$/=10">Hi!</span> </div> <ul data-reactid=".0.$/=11"> <li data-reactid=".0.$/=11.0">Some</li> <li data-reactid=".0.$/=11.1">Other</li> <li data-reactid=".0.$/=11.2">Component</li> </ul> <div data-rendered-by="Foo" data-reactid=".0.$/=12=20"> <span data-rendered-by="Foo" data-reactid=".0.$/=12=20.$/=10">a</span> </div> <div data-rendered-by="Foo" data-reactid=".0.$/=12=21"> <span data-rendered-by="Foo" data-reactid=".0.$/=12=21.$/=10">b</span> </div> <div data-rendered-by="Foo" data-reactid=".0.$/=12=22"> <span data-rendered-by="Foo" data-reactid=".0.$/=12=22.$/=10">c</span> </div> </div>
Here, each DOM node has a data-rendered-by="Foo" attribute, which allows you only from the DOM to indicate that the node was mapped to Foo .
Here is a working example in JSBin: https://jsbin.com/tuliqu/edit?js,output
This is a pretty powerful abstraction that can allow you to do what you want without even touching the DOM; for example, in React CSS Modules, the DOM is not affected - the components are simply expanded and the render is redefined .