I have a loop that reads multiple elements from the document and I render it with ReactDOM.render
, and a component very low in the component tree, creates a custom event
, to that event I would like to pass the element that was rendered in the DOM (i.e. Root Element), I have to go passing from the top the element through Props, or React provides some API that can tell me which Root element we are?
Rather, in the child component, I would like to make: rootElement.dispatchEvent(myCustomEvent)
;
What options do I have to do this?
CodePudding user response:
The root node looks to be given a property that starts with __reactContainer
, so you can search through parent elements until you find an element with such a property.
const Child = () => <div><span onClick={(e) => {
let element = e.target;
while (element) {
element = element.parentElement;
if (Object.keys(element).some(key => key.includes('reactContainer'))) {
console.log('Found', element);
break;
}
}
}}>click</span></div>;
const App = () => {
return <section><Child /></section>
};
ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>
That's almost certainly not part of the deliberate outward-facing design, though. A better way would be to use useContext
to save the root element at the top component via a ref, and to consume it in the descendant component.
const Child = () => {
const { ref } = React.useContext(Context);
return (
<div>
<span
onClick={() => { console.log(ref.current.parentElement); }}
>click</span>
</div>
);
};
const Context = React.createContext();
const App = () => {
const ref = React.useRef();
return (
<Context.Provider value={{ref}}>
<section ref={ref}><Child /></section>
</Context.Provider>
);
};
ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>