Что такое конвертация HTML в JSX?
Конвертация HTML в JSX — это процесс преобразования стандартной HTML-разметки в JSX-синтаксис, который React-компоненты могут использовать для рендеринга. JSX выглядит похоже на HTML, но следует соглашениям и правилам JavaScript. Атрибуты вроде class становятся className, for становится htmlFor, а строки инлайн-стилей заменяются объектами JavaScript. Эти изменения обязательны, потому что JSX компилируется в вызовы React.createElement(), где имена атрибутов должны совпадать с именами свойств DOM API, а не с именами HTML-атрибутов.
Соответствие между HTML-атрибутами и JSX-пропсами определено в документации React по DOM-элементам. React использует camelCase для составных атрибутов (tabindex становится tabIndex, maxlength становится maxLength), потому что идентификаторы JavaScript не могут содержать дефисы. Самозакрывающиеся теги вроде <img>, <br> и <input> должны включать завершающий слэш в JSX (<img />), поскольку JSX следует правилам XML, где каждый тег должен быть явно закрыт.
Помимо переименования атрибутов, конвертация HTML в JSX также затрагивает инлайн-стили и комментарии. Атрибуты стилей HTML используют синтаксис CSS в виде строки (style="color: red; font-size: 14px"), тогда как JSX ожидает объект JavaScript с camelCase-именами свойств (style={{ color: 'red', fontSize: '14px' }}). HTML-комментарии (<!-- -->) превращаются в JSX-комментарии выражений ({/* */}). Пропуск любого из этих преобразований приводит к ошибкам во время выполнения или незаметным ошибкам рендеринга в React-приложениях.
Зачем использовать конвертер HTML в JSX?
Переименовывать атрибуты и переписывать строки стилей вручную в десятках HTML-элементов — это долго и ненадёжно. Конвертер выполняет все преобразования за один раз: вставляешь HTML из любого источника и получаешь корректный JSX за секунды.
Примеры использования HTML в JSX
Справочник по соответствию атрибутов HTML и JSX
В таблице ниже перечислены HTML-атрибуты, которые изменяются при конвертации в JSX. Атрибуты, не указанные здесь (id, src, href, alt, placeholder и др.), остаются без изменений, поскольку их HTML-имена уже совпадают с соответствующими именами свойств DOM API.
| HTML-атрибут | JSX-проп | Примечания |
|---|---|---|
| class | className | Reserved word in JavaScript |
| for | htmlFor | Reserved word in JavaScript |
| tabindex | tabIndex | camelCase convention |
| readonly | readOnly | camelCase convention |
| maxlength | maxLength | camelCase convention |
| minlength | minLength | camelCase convention |
| cellpadding | cellPadding | camelCase convention |
| cellspacing | cellSpacing | camelCase convention |
| rowspan | rowSpan | camelCase convention |
| colspan | colSpan | camelCase convention |
| enctype | encType | camelCase convention |
| autocomplete | autoComplete | camelCase convention |
| autofocus | autoFocus | camelCase convention |
| autoplay | autoPlay | camelCase convention |
| contenteditable | contentEditable | camelCase convention |
| crossorigin | crossOrigin | camelCase convention |
| novalidate | noValidate | camelCase convention |
| allowfullscreen | allowFullScreen | camelCase convention |
| spellcheck | spellCheck | camelCase convention |
| http-equiv | httpEquiv | Hyphen removed, camelCase |
| onclick | onClick | Event handler camelCase |
| onchange | onChange | Event handler camelCase |
| onsubmit | onSubmit | Event handler camelCase |
Конвертация инлайн-стилей: HTML vs JSX
Инлайн-стили — наиболее сложная для конвертации часть HTML в JSX, поскольку меняются и формат значения, и имена свойств:
<div style="background-color: #fff; font-size: 14px; margin-top: 10px;">
<div style={{
backgroundColor: '#fff',
fontSize: '14px',
marginTop: 10
}}>Примеры кода
Приведённые примеры демонстрируют программную конвертацию HTML в JSX на разных языках и в разных окружениях. Каждый пример охватывает переименование атрибутов, конвертацию стилей и обработку самозакрывающихся тегов.
// Simple attribute conversion using string replacement
function htmlToJsx(html) {
return html
.replace(/\bclass=/g, 'className=')
.replace(/\bfor=/g, 'htmlFor=')
.replace(/\btabindex=/g, 'tabIndex=')
.replace(/<!--([\s\S]*?)-->/g, '{/*$1*/}')
}
htmlToJsx('<div class="box" tabindex="0"><!-- note --></div>')
// → '<div className="box" tabIndex="0">{/* note */}</div>'import parse from 'html-react-parser'
// Parse HTML string into React elements (handles all JSX rules)
const element = parse('<div class="card"><img src="photo.jpg" alt="Photo"></div>')
// Returns: React.createElement('div', { className: 'card' },
// React.createElement('img', { src: 'photo.jpg', alt: 'Photo' }))
// With custom element replacement
const options = {
replace(domNode) {
if (domNode.name === 'img') {
return <OptimizedImage src={domNode.attribs.src} alt={domNode.attribs.alt} />
}
}
}
const custom = parse('<img src="photo.jpg" alt="Photo">', options)from bs4 import BeautifulSoup
import re
ATTR_MAP = {
'class': 'className', 'for': 'htmlFor',
'tabindex': 'tabIndex', 'readonly': 'readOnly',
'maxlength': 'maxLength', 'autocomplete': 'autoComplete',
}
def html_to_jsx(html: str) -> str:
"""Convert HTML attribute names to JSX equivalents."""
for html_attr, jsx_attr in ATTR_MAP.items():
html = re.sub(rf'\b{html_attr}=', f'{jsx_attr}=', html)
# Convert HTML comments to JSX comments
html = re.sub(r'<!--(.*?)-->', r'{/*\1*/}', html)
return html
print(html_to_jsx('<label for="email" class="field">Email</label>'))
# → '<label htmlFor="email" className="field">Email</label>'package main
import (
"fmt"
"strings"
)
var attrMap = map[string]string{
"class=": "className=",
"for=": "htmlFor=",
"tabindex=": "tabIndex=",
"readonly": "readOnly",
}
func htmlToJSX(html string) string {
result := html
for old, new := range attrMap {
result = strings.ReplaceAll(result, old, new)
}
// Convert comments
result = strings.ReplaceAll(result, "<!--", "{/*")
result = strings.ReplaceAll(result, "-->", "*/}")
return result
}
func main() {
html := `<div class="wrapper"><input readonly tabindex="1"></div>`
fmt.Println(htmlToJSX(html))
// → <div className="wrapper"><input readOnly tabIndex="1"></div>
}