ReactFix
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • React
  • React Native
  • Programming
  • Object Oriented Programming

Thursday, November 10, 2022

[FIXED] How to render child component outside of its parent component (DOM Hierarchy) - React.js

 November 10, 2022     css, javascript, reactjs   

Issue

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>
...

Solution

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



Answered By - Sedat Polat
Answer Checked By - - Timothy Miller (ReactFix Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Newer Post Older Post Home

Featured Post

Is Learning React Difficult?

React is difficult to learn, no ifs and buts. React isn't inherently difficult to learn. It's a framework that's different from ...

Total Pageviews

Copyright © ReactFix