React - отличный инструмент не только для HTML, но и для безопасного и эргономичного создания любого документа на основе XML. Фактически, мы использовали немного больше, чем React + SVG, чтобы построить весь редактор топо-кода в Boltline:
JSX ≠ HTML
Однако есть пара вещей, которые очень важно помнить при использовании React для XML. Несмотря на «разметку» JSX, на самом деле вы создаете не строки, а объект JS; поля не обязательно соответствуют атрибутам HTML, но относятся к свойствам DOM или свойствам React, основанным на DOM. Вот почему вы используете className
вместо class
.
Поэтому, когда вам нужно добавить xlink:href="https://example.com"
, вы захотите использовать xlinkHref="https://example.com"
(обратите внимание на camelCase).
Это отлично подходит для поддерживаемых атрибутов, которые включают практически все, что вам нужно для SVG.
JSX ≠ XML
Однако это перестает работать, когда вам нужны более продвинутые функции XML. JSX совершенно ясно, что его цель - не полной поддержки XML. Давайте попробуем добавить расширение изображений Google в наш файл sitemap.xml, созданный с помощью реакции:
... <image:image> <image:loc>http://example.com/image.jpg</image:loc> </image:image> ...
Это ломается с очень явной ошибкой:
ERROR in ./SitemapXMLRoot.js Module build failed: SyntaxError: Namespace tags are not supported. ReactJSX is not XML. > 181 | <image:image> | ^ 182 | <image:loc>http://example.com/image.jpg</image:loc> 183 | </image:image>
Хотя JSX не справляется с этой задачей, на самом деле React справляется! Мы можем пойти дальше и использовать необработанные React.createElement
вызовы для создания пользовательских компонентов React, готовых к JSX, которые отображают наши пользовательские элементы XML:
const ImageImage = (p: *) => { const { children, ...props } = p; return React.createElement("image:image", props, children); }; const ImageLoc = (p: *) => { const { children, ...props } = p; return React.createElement("image:loc", props, children); };
А теперь воспользуемся ими:
... <ImageImage> <ImageLoc>http://example.com/image.jpg</ImageLoc> </ImageImage> ...
И это работает! Это отображает наши элементы image:image
и image:loc
, как мы и хотели:
И еще кое-что.
Мы еще не определили пространство имен image:
. Хотя React 16+ будет передавать настраиваемые атрибуты, двоеточие нарушает синтаксис JSX. Это легко обойти с помощью оператора распространения JSX:
const namespaces = { "xmlns:image": "http://www.google.com/schemas/sitemap-image/1.1" }; <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" {...namespaces} >
Посетите страницу React, посвященную элементам DOM, чтобы узнать больше!