Особенностью ReactJS является использование смеси HTML и Javascript для большей читаемости, например:
render: function(){ return <div> <div class="clicker" onMouseDown={this.handleMouseDown}> Give me the message! </div> <div class="message">Message conveyed <span class="count">{this.state.count}</span> time(s)</div> </div> ; }
Этот язык называется JSX и перед его использованием в браузере специальная утилита конвертирует все в простой Javascript. Результат получается такой:
render: function(){ return React.DOM.div(null, React.DOM.div( {className:"clicker", onMouseDown:this.handleMouseDown}, " Give me the message! " ), React.DOM.div( {className:"message"}, "Message conveyed ", React.DOM.span( {className:"count"}, this.state.count), " time(s)") ) ; }
Можно не использовать JSX и сразу писать на Javascript, но этот подход более трудоемкий и менее читабельный. С другой стороны, использование JSX накладывает ряд требований, которые нежелательны, как то:
* использование дополнительного редактора для разметки JSX
* использование дополнительной утилиты для прекомпиляции JSX
* отказ от использования TypeScript
Отказ от TypeScript для меня неприемлим, поэтому родилась такая идея: улучшить читабельность за счет применения удобной обьектной структуры Javascript и затем генерировать код React.DOM, опять на Javascript, вообще без JSX. Получилось так:
render: function () { var dom = [ { tag: React.DOM.div, props: { className: "class1", onClick: this.handleClick }, content: "Hello " + this.state.value }, { tag: React.DOM.span, props: { }, dom: [ { tag: React.DOM.span, props: { className: "class2" }, content: "Hello " + this.state.value } ] } ]; return parse(dom); }
Таким образом, создается структура на основе массива объектов, каждый из которых содержит 3 свойства: tag, props и dom (если есть вложенные объекты) или content (если этот объект листовой). Функция, которая создает код для ReactJS такая:
function parse(dom, inner) { var items = []; for (var el in dom) { if (dom[el].dom) { items.push(dom[el].tag(dom[el].props, parse(dom[el].dom, inner || true))); } else { items.push(dom[el].tag(dom[el].props, dom[el].content)); } } if (inner) { return items.length == 1 ? items[0] : items; } else { return items.length == 1 ? items[0] : React.DOM.section(null, items); } }
По результатам подход оказался очень удобным. Заметных потерь при отрисовке не обнаружено, но не исключаю, что на сложных интерфейсах все-же придется создавать DOM на основе примитивов React. В любом случае, этот шаг оптимизации можно будет выполнить на заключительной стадии, после утряски собственно компонентов.
Комментарии (11)
DarthVictor
17.11.2016 16:10+3Typescript прекрасно поддерживает TSX, при этом еще и проверку типов для props во время компиляции проводит.
https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
shanhaichik
17.11.2016 16:19+1Возможно мысль и благая, но лично меня смущает возможный просмотр листингов хотя бы среднего компонента в таком стиле. Какой-нибудь формочки, например.
Во-первых, на мне кажется, что увеличивается возможность допустить ошибку
Во-вторых, да же на среднем мониторе будет сложно это просматривать. Возможно кровотечение из глаз и поломку мозгаFrozik
17.11.2016 16:23Ага, чем-то мне это напоминает BEMJSON. Но большие листинги даже для jsx это зло и трудно для чтения.
shanhaichik
17.11.2016 16:26Согласен.
Касательно BEMJSON, возможно, когда-то смотрел, но лично дело не имел.
justboris
17.11.2016 17:55+4Так можно же так:
const {div, span} = React.DOM; render() { return div({className: "class1", onClick: this.handleClick}, "Hello " + this.state.value, div({}, span({}, span({}, "Hello " + this.state.value) ) ) ); }
Это обычный Javascript/Typescript код, и смотрится довольно читабельно. И ничего парсить не надо.
Вот рабочий пример:
http://codepen.io/anon/pen/RoopYY?editors=0010
Frozik
А зачем отказываться от Typescript, если c версии 1.6 он поддерживает JSX? Ну и на счет редакторов отдельных, вроде все основные сейчас поддерживают JSX синтаксис с удобным редактированием…
Frozik
Хотел добавить, что, например, при использовании TSLint, будет удобно использовать JSX, а в вашей ситуации он не поймет этого и будет применять общие правила, не делая подсказки специфичные для JSX…
impwx
Именно — Typescript уже чуть больше года решает все три ключевых проблемы JSX, из-за которых автор решил изобрести свой велосипед. Неудобно получилось…