如何在其父组件(DOM 层次结构)之外渲染子组件 - React.js

Sed*_*lat 3 javascript css reactjs

我有一个表格组件,它有粘性标题,表格主体行包含下拉菜单、省略号菜单和一些其他复杂的组件。表的每一行内部都有另一个表主体行,父行也对其子表主体行具有粘性。下拉菜单和省略号菜单位于下一个粘性行后面。由于粘性行,设置 z-index 是不够的。唯一的方法是在表格之外呈现菜单并提供更大的 z-index。

使问题更容易理解;假设渲染方法如下:

return <div id='parent'>
            <input />
            <span id='child'>{value}</span>
       </div>;
Run Code Online (Sandbox Code Playgroud)

我想在 DOM 层次结构之外child进行渲染:parent

...
<body>
    <div id='parent'> <input /> </div>
    <div id='child'></div>
<body>
...
Run Code Online (Sandbox Code Playgroud)

Sed*_*lat 10

经过快速搜索,我找到了React Portal在父组件(DOM 层次结构)之外渲染子组件 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>);
};
Run Code Online (Sandbox Code Playgroud)

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>;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

github 上的示例: https: //github.com/sedpol/react-portal