Динамическое отображение внешних компонентов HTML / React в React

Можно ли взять содержимое HTML / JSX из внешнего источника и динамически отображать его в React? В нашем случае мы хотим взять контент из Wordpress API и отобразить его как на клиенте, так и на сервере (мы используем NextJS).

Итак, API Wordpress возвращает ответ JSON, который включает свойство содержимого, которое представляет собой строку HTML / JSX. содержимое будет выглядеть примерно так.

{
    content: "<div><Slider imageCount="5" galleryID="1"></Slider><span>This is an image gallery</span></div>"
}

Итак, как вы можете видеть, это будет смесь компонентов HTML и React / JSX, представленная в виде строки

Я бы использовал Axios, чтобы сделать вызов для получения контента (как на сервере, так и на клиенте с использованием метода NextJS getInitialProps ()), затем мне нужно его отрендерить, но я новичок в реакции и вижу пару проблем.

1) В React JSX компилируется во время сборки, а не во время выполнения, я не вижу, как это обойти (это было бы легко в Angular, используя, например, службу $ compile).

2) Поскольку мы не знаем, какие компоненты будет использовать контент из Wordpress, нам придется импортировать каждый из них в верхней части страницы, контент может включать компонент или он может включать компонент, кто знает?.

Прямо сейчас я думаю, что это невозможно, а это значит, что нам придется пересмотреть использование React, но я очень надеюсь, что у кого-то есть ответ.

Любая помощь будет оценена по достоинству.


person jonhobbs    schedule 23.07.2018    source источник
comment
Возможно, вы могли бы проанализировать строку (с регулярным выражением, совпадающим только с тегами с заглавными буквами), чтобы определить классы, используемые в ней, а затем заменить эти части (<Slider ... </Slider>) на обработанный ответ, а затем использовать dangerouslySetInnerHtml. Имеет ли это смысл ?   -  person ChrisR    schedule 26.07.2018
comment
Это имеет смысл, это средний бит, заменяющий эти части отрендеренной реакцией, что я не знаю, как это сделать. Где бы я это сделал?   -  person jonhobbs    schedule 26.07.2018
comment
Почему вместо получения строки, которая может содержать JSX, вы можете построить строку при сохранении, а при извлечении вам понадобится только пакет, который является выходом этой сборки, используя import('url-to-bundle'), а затем отобразить его с помощью React.   -  person felixmosh    schedule 19.02.2019
comment
хотя это не совсем то, о чем спрашивает OP, если вы хотите динамически отображать компоненты реакции из отдельного пакета во время выполнения, ознакомьтесь с моим ответом здесь https://stackoverflow.com/a/61823689/800619   -  person NSjonas    schedule 15.05.2020


Ответы (3)


Интересная проблема!

Вам следует попробовать react-jsx-parser. Думаю, это решит твои проблемы. Не знаю, как это работает с Next JS - у меня нет опыта работы с Next JS.

Оцените эту песочницу:  Изменить 24r1ypp00p


Вы правы насчет комплектации всех компонентов. Для этого есть обходной путь. :)

Оцените эту песочницу:  Изменить 24r1ypp00p

Я создал dynamicComponent, который ожидает обещание импорта и возвращает компонент.

Я изменил способ импорта компонентов A, B и C в index.js. Таким образом, каждый динамически импортированный компонент получает отдельный пакет и запрашивается только при необходимости.

Это должно решить вашу вторую проблему.

person bamse    schedule 26.07.2018
comment
Это очень интересно, похоже, что это может работать на интерфейсе, если я импортирую каждый компонент React в верхней части страницы, который может выводить CMS. Собираемся исследовать это немного дальше. - person jonhobbs; 26.07.2018
comment
react-jsx-parser, похоже, добавляет недостающую ссылку: импорт компонентов в FE, чтобы они были доступны, когда / если отображается динамически - person bamse; 26.07.2018
comment
В их примере ComponentA, B, C, D все импортируются в верхней части страницы, поэтому предположительно попадают в пакет независимо от того, нужны ли они JSX-парсеру для рендеринга строки. Если только я что-то не понял. - person jonhobbs; 26.07.2018
comment
Исходя из моего ограниченного понимания NExtJS, он отображает вашу страницу в исходной и серверной части одинаково, поэтому мне не нужно делать что-либо иное для ее части SSR, но я собираюсь попросить сообщество NextJS убедиться. Я также не уверен, каковы последствия для безопасности при извлечении строки из моей CMS с помощью Axios, а затем ее синтаксическом анализе во внешнем интерфейсе? - person jonhobbs; 26.07.2018
comment
Я обновил ответ, чтобы указать, какие компоненты собираются в комплекте. С точки зрения безопасности, я не знаю, что сказать :) Я бы назвал это временным решением, пока вещи не будут перенесены на что-то более простое в обслуживании и более простое. Получение строк из CMS и их рендеринг на FE может оказаться нестабильным и сложным в обслуживании, но это может дать вам некоторое время для миграции. Надеюсь, это поможет! - person bamse; 26.07.2018
comment
Спасибо @bamse. Я отметил правильность и добавлю +250 репутации, как только мне будет разрешено. Однако это не временное решение. Мы хотим, чтобы наши клиенты могли использовать Wordpress для редактирования своего контента, и мы хотим иметь возможность создавать сайт в React, поэтому я не уверен, что когда-либо будет лучшее решение. - person jonhobbs; 26.07.2018

Вы можете обратиться к приведенной ниже ссылке

https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

Для части React Components вы можете отобразить строку статической разметки HTML, используя

https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup

Но убедитесь, что HTML-код, который вы получаете, взят из подлинного источника и не будет содержать вредоносных скриптов.

person Gokul    schedule 23.07.2018
comment
Прочитав эту ссылку, я не уверен, что вторая часть будет работать. Разметка должна отображаться как на сервере, так и на клиенте, и должна быть полностью функциональной. - person jonhobbs; 23.07.2018
comment
В случае полностью функционального динамического компонента вам понадобятся компоненты как на сервере, так и на клиенте. Но, однако, нет необходимости импортировать все компоненты. Вы можете попробовать динамический импорт и разделить код таким образом, чтобы все ваши компоненты не были загружены в render reactjs.org/docs/code-splitting.html - person Gokul; 23.07.2018
comment
Извините, я не понимаю, как это решает мою проблему. Мне не нужно использовать два разных решения для HTML и компонентов, мне нужно что-то, что преобразует строку HTML / JSX в рабочий компонент реакции и дочерние компоненты в Next JS, на интерфейсном и внутреннем интерфейсе - person jonhobbs; 23.07.2018
comment
Вам нужно будет импортировать все компоненты вверху и использовать их, это единственное решение, о котором я могу думать :), я добавил ссылку на разделение кода в качестве оптимизации для динамического импорта - person Gokul; 29.07.2018

Вы можете рендерить внешние компоненты HTML / React динамически в React вот так, просто в этой цитате , content: `<div>${<Slider imageCount="5" galleryID="1"></Slider>}<span>This is an image gallery</span></div>

заканчивается этим знаком `.

person Salman Mehmood    schedule 23.07.2018
comment
Я не понимаю, как использование литерала шаблона сделает мою строку полнофункциональной React? - person jonhobbs; 23.07.2018