Как отобразить дочерний компонент вне его родительского компонента (иерархия DOM) - React. js - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть компонент таблицы, у которого есть липкие заголовки, а строки тела таблицы содержат дописки, меню с многоточием и некоторые другие сложные компоненты. В каждой строке таблицы есть еще строки тела таблицы, и родительские строки также привязаны к строкам тела дочерней таблицы. Раскрывающееся меню с многоточием остается рядом со следующим склеенным рядом. Установка z-index не достаточно из-за липких строк. Единственный способ - сделать меню вне таблицы и дать больший z-индекс.

Чтобы облегчить понимание вопроса; Допустим, метод рендеринга выглядит так:

return <div id='parent'>
            <input />
            <span id='child'>{value}</span>
       </div>;

Я хочу отрендерить child вне parent в результате иерархии DOM:

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

1 Ответ

0 голосов
/ 26 апреля 2020

После быстрого поиска я нашел React Portal подход к отображению дочернего компонента html вне родительского компонента (иерархия DOM).

Component:

import React, { useState} из 'Reaction'; import {Portal} из '../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 реализация с 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...