Как заставить Antd добавлять элемент как дочерний элемент div, который рендерит в React, а не в тело HTML? - PullRequest
2 голосов
/ 07 ноября 2019

Редактировать:

Я понял это и опубликовал ответ ниже.


Оригинальный вопрос

Я пытаюсь создать полностью разобщенное веб-приложение в тени-dom, и я использовал компоненты Antd и столкнулся с проблемой, когда Antd добавляет выпадающие параметры в тег body, а не как дочерний элемент элемента, в который React рендерит.

Чтобы изолировать этоПроблема Я удалил все, кроме React.render и одного элемента Antd, который все еще делает то же самое.

Затем я использовал другой компонент, "response-date-picker", который работает так, как янадеялся, что это сделает Antd, где компонент рендерится как дочерний элемент для div, заданного для реагирования.

К сожалению, рендеринг Antd в тело HTML вместо дочернего делает использование теневого корня бессмысленным.

По сути, мой вопрос:

Это нормальная функциональность этого Antd? Если нет, то что я могу испортить, чтобы это произошло? Если это так, то есть ли встроенная опция Antd, которую я пропускаю и которая отображает опции Antd как дочерние элементы? Если эта опция не существует в их библиотеках, есть ли способ заставить Antd отображать как дочерний узел моего теневого корневого узла?

Вот что я использую для отображения Antd DatePickerКомпонент:

import ReactDOM from 'react-dom';
import React from 'react';
import DatePicker from 'antd/lib/date-picker';
ReactDOM.render(<DatePicker/>, document.getElementById('entry-fields'));

Перед нажатием на кнопку выбора даты Antd: before antd date-picker clicked

После нажатия на нее опции раскрывающегося списка добавляются к <body>, а не <div id="entry-fields>: after antd date-picker clicked

Вот то, что я использую для визуализации компонента выбора даты реакции, чтобы продемонстрировать ожидаемую / нужную функциональность:

import ReactDOM from 'react-dom';
import React from 'react';
import DatePicker from "react-datepicker";
class Example extends React.Component {
    state = {
        startDate: new Date()
    };

    handleChange = (date: any) => {
        this.setState({
            startDate: date
        });
    };

    render() {
        return (
            <DatePicker
                selected={this.state.startDate}
                onChange={this.handleChange}
            />
        );
    }
}
ReactDOM.render(<Example/>, document.getElementById('entry-fields'));

Перед нажатием на кнопку выбора даты реакциисредство выбора даты: before react-date-picker clicked

После нажатия на средство выбора даты реагировать на дату (раскрывающиеся параметры добавляются при отображении дочерних элементов элемента реакции): after react-date-picker clicked

По сути, я ожидал, что Antd представит свои параметры, инкапсулированные в React, в <div></div>, но вместо этого он добавляет элементы в <body></body>.

Я относительно неопытен в области web-dev и прибегаю кспрашиваяздесь, слишком много времени, пытаясь найти ответ самостоятельно. Я очень разочарован в web-dev в целом, где любой вопрос, кажется, приводит к сотням ненужных постов в среднем блоге, которые бесполезны в любом качестве ... при условии, что это не просто я, не зная, что искать, чтобы найти ответыМне нужно, что вполне может иметь место.

Очень ценю любую помощь заранее.

1 Ответ

1 голос
/ 07 ноября 2019

Не знаю, как мне удалось пропустить это, но в Antd есть параметр с именем "getCalendarContainer", который, если оставить его пустым, отобразит параметры в теле документа, но если он будет предоставлен с правильными параметрами, будет отображать дочерние элементы в контейнере вашегоВыбор.

Выходя из этого примера: https://react -component.github.io / calendar / examples / getCalendarContainer.html

Я заработал, добавив эту функциюк моему компоненту:

getCalendarContainer() 
{
    return this.d || document.getElementById('calendarContainer');
}

и добавьте это к компоненту в JSX:

<div id="calendarContainer"  ref={n => (this.d = n as HTMLDivElement)} >
    <DatePicker onChange={EntryFields.onDateChange} getCalendarContainer={this.getCalendarContainer}/>
</div>

и инициализируйте тег div для ссылки на него в конструкторе компонента следующим образом:

private d: HTMLDivElement;
constructor(props: any)
{
    super(props);
    this.d = document.createElement("div");
...

Стоит также отметить, что вышеприведенное не будет работать сразу при использовании shadow-DOM, поскольку вам нужно получить доступ к узлу, для которого shadow-DOM является дочерним, и затем использовать getElementById ().

Что-то в этом роде (но, вероятно, лучше написано, я надеюсь, lol)

    getContainer() {
        let elem = null;
        let shadowContainer = document.getElementById('entryFieldsShadow')  as HTMLInputElement;
        if (shadowContainer != null) {
            let shadowDom = shadowContainer.firstElementChild;
            if (shadowDom != null) {
                let shadowRoot = shadowDom.shadowRoot;
                if (shadowRoot != null) {
                    elem = shadowRoot.getElementById("entryFieldsContainer")
                }
            }
        }
        return elem || this.d;
    }

, где включен JSX с теневым корнем реагирующей тенивот так:

return (
            <div id="entryFieldsShadow">
                <root.div>
                    <div>
                        <div id="entryFieldsContainer"/>
                        <style type="text/css"> @import "static/1.css"; </style>
                        <Layout>
                            <Content>
                                {this.RowCols()}
                            </Content>
                        </Layout>
                    </div>
                </root.div>
            </div>
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...