简体   繁体   English

如何在其父组件之外渲染子组件(DOM Hierarchy) - React.js

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

I have a table component which has sticky headers and table body rows contains 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.由于粘性行,设置 z-index 是不够的。 Only way is to render menus outside of the table and give greater z-index.唯一的方法是在表格之外渲染菜单并提供更大的 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:由于 DOM 层次结构,我想在parent级之外渲染child级:

...
<body>
    <div id='parent'> <input /> </div>
    <div id='child'></div>
<body>
...

After a quick search, I found React Portal approach to render child component html outside of the parent component(DOM Hierarchy).经过快速搜索,我发现React Portal方法可以在父组件(DOM Hierarchy)之外渲染子组件 html。

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 : Portal.js 使用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>

https://github.com/sedpol/react-portal https://github.com/sedpol/react-portal

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM