React 16.6 ленивое / приостановленное исключение DOM

Я пытаюсь включить динамический импорт в своем приложении React. Большинство примеров React отображает приложение для некоторого тега, заменяющего контент, например:

ReactDOM.render(<App />,  document.getElementById('app'));

Но мне нужно сохранить статический блок внутри элемента #app и отобразить React следующим образом:

let container = document.createElement('div');
ReactDOM.render(<App />, container);
let app = document.getElementById('app');
app.appendChild(container);
let renderedHeader = container.querySelector('#header');
let renderedWrapper = container.querySelector('#wrapper');
app.querySelector('#header').replaceWith(renderedHeader);
app.querySelector('#wrapper').replaceWith(renderedWrapper);

Все работает так, как ожидалось, пока я не попробую использовать компоненты lazy / Suspense.

Вот (Суть / Stackblitz) полный пример, который бросает DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. внутри компонента Suspense.

Это моя проблема или проблема с задержкой?

Есть ли более распространенный способ визуализации приложения React, но с сохранением статических блоков?

Почему статический элемент не может быть просто еще одним компонентом React? Это был бы идеальный способ (не знаю, решит ли он вашу проблему)

Matthew Herbst 10.12.2018 08:57

Он должен быть достигнут на сервере в статическом файле устаревшими приложениями.

vitalyster 10.12.2018 08:59

Что ты имеешь в виду? Содержимое статического объекта извлекается с сервера? Если это так, используйте dangerouslySetInnerHTML для загрузки данных в ваш компонент после его загрузки.

Matthew Herbst 10.12.2018 09:01

@MatthewHerbst Да, именно так

vitalyster 10.12.2018 09:02

Нет, я не могу установить HTML в приложении React, мне нужно, чтобы он был там до React, так как устаревшее приложение не поддерживает javascript

vitalyster 10.12.2018 09:03

Подумайте о предоставлении работоспособной демонстрации, которую можно хотя бы отладить. Кроме того, демонстрация, размещенная на Stackblitz или другом сервисе, имеет больше шансов выжить с течением времени, чем ваша собственная суть.

Estus Flask 10.12.2018 09:06

Извините, у меня нет опыта работы со Stackblitz или "другим сервисом", попробую его настроить.

vitalyster 10.12.2018 09:08

@estus добавил ссылку на stackblitz

vitalyster 10.12.2018 09:15

Я понимаю. Это не проблема с задержкой, вам просто не нужно изменять DOM вручную. Селекторы #header и т. д. Относятся к разным элементам в разные моменты времени. Я не уверен, как именно нужно реорганизовать код в вашем случае, но это обычное применение для порталов. См., Например, stackoverflow.com/questions/53557119/… или stackoverflow.com/a/52408076/3731501.

Estus Flask 10.12.2018 09:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
9
322
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема здесь в том, что селекторы #header и #wrapper ссылаются на разные элементы в разные моменты времени.

В момент выполнения container.querySelector('#header')#header ссылается на <div id = "header"> в резервном компоненте (LoadingView), который предполагается удалить из DOM позже.

Предпочтительно рассматривать Header и Wrapper как разные компоненты и монтировать их в существующие заполнители <div id = "header"> и <div id = "wrapper"> как порталы. Они по-прежнему могут быть вложены в родительский компонент (App или Main) для совместного использования состояния между ними.

Интересный. Но createPortal добавляет компонент к #header как дочерний и не удаляет его старое содержимое. Я что-то скучаю?

vitalyster 10.12.2018 10:35

Если это единственное препятствие, вы можете заранее очистить содержимое #header, чтобы удалить материал Header template.

Estus Flask 10.12.2018 10:43

Если я делаю document.getelementbyid('header').innerHTML='', я получаю то же исключение DOM, что и раньше

vitalyster 10.12.2018 10:44

Вы делаете это с порталами? Можете ли вы предоставить демонстрацию того, как вы это делаете?

Estus Flask 10.12.2018 10:46

Решена проблема, не предоставляя заголовок в загружаемом компоненте, который мне не нужен для обновления заголовка в режиме загрузки.

vitalyster 10.12.2018 10:57

Да, это идея. Проблема заключалась в том, что вы очистили содержимое #header, где портал заголовка уже отображался. Поскольку Header не должен знать, что это портал, вы можете переместить ReactDOM.createPortal и innerHTML в Main.

Estus Flask 10.12.2018 11:06

Другие вопросы по теме