Reputation: 1721
I have a table component which has sticky headers and table body rows contain dopdowns, ellipsis menu and some other complex components. Each row of the table has another table body rows inside and parent rows are also sticky for their child table body rows. Dropdown and ellipsis menu stay behinde the next sticky row. Setting z-index is not enough because of the sticky rows. Only way is to render menus outside of the table and give a greater z-index.
To make the question easier to understand; Let's say render method is like:
return <div id='parent'>
<input />
<span id='child'>{value}</span>
</div>;
I want to render child
outside of parent
as a result of DOM Hierarchy:
...
<body>
<div id='parent'> <input /> </div>
<div id='child'></div>
<body>
...
Upvotes: 3
Views: 7871
Reputation: 1721
After a quick search, I found React Portal
approach to render child component html outside of the parent component (DOM Hierarchy).
Component:
import React, { useState } from 'react';
import { Portal } from '../Portal/Portal';
export const FirstPage = () => {
const [value, setValue] = useState('');
return (
<div id='parent'>
<input onChange={e => {setValue(e.target.value)}} value={value} />
<Portal>
<span id='child'>{value}</span>
</Portal>
</div>);
};
Portal.js implementation with React Hooks
:
import React, { useEffect, useRef } from "react"
import ReactDOM from 'react-dom';
export const Portal = (props) => {
const el = useRef(document.createElement('div'));
useEffect(() => {
const portal = document.getElementById('portal');
portal.appendChild(el.current);
return () => {
portal.removeChild(el.current);
};
}, [props.children]);
return ReactDOM.createPortal(props.children, el.current);
}
export const PortalDiv = () => <div id='portal'></div>;
App.js:
import React from 'react';
import './App.css';
import { PortalDiv } from './Portal/Portal';
import { FirstPage } from './Pages/FirstPage';
function App() {
return (
<div className="App">
<FirstPage />
<PortalDiv />
</div>
);
}
export default App;
Result:
<div class="App">
<div id="parent">
<input value="random text">
</div>
<div id="portal">
<div><span id="child">random text</span></div>
</div>
</div>
Example on github: https://github.com/sedpol/react-portal
Upvotes: 10