admin管理员组

文章数量:1296895

I have a table ponent which has sticky headers and table body rows contain dopdowns, ellipsis menu and some other plex ponents. 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>
...

I have a table ponent which has sticky headers and table body rows contain dopdowns, ellipsis menu and some other plex ponents. 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>
...
Share Improve this question edited Jan 14, 2022 at 11:43 Sedat Polat asked Apr 25, 2020 at 21:30 Sedat PolatSedat Polat 1,7213 gold badges20 silver badges30 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 10

After a quick search, I found React Portal approach to render child ponent html outside of the parent ponent (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./sedpol/react-portal

本文标签: