ReactJS — это Javascript библиотека для разработки веб-компонентов на основе виртуального DOM. ReactJS стал уже достаточно популярен за тот год, как его выпустила в свет компания Facebook. В ближайшее время можно ожидать интереса к этой библиотеке со стороны еще большего количества компаний, потому что ReactJS позволяет создавать надежные, производительные интерфейсы быстро.

Особенностью 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)


  1. Frozik
    17.11.2016 15:57
    +8

    А зачем отказываться от Typescript, если c версии 1.6 он поддерживает JSX? Ну и на счет редакторов отдельных, вроде все основные сейчас поддерживают JSX синтаксис с удобным редактированием…


    1. Frozik
      17.11.2016 16:02

      Хотел добавить, что, например, при использовании TSLint, будет удобно использовать JSX, а в вашей ситуации он не поймет этого и будет применять общие правила, не делая подсказки специфичные для JSX…


    1. impwx
      17.11.2016 16:08
      +1

      Именно — Typescript уже чуть больше года решает все три ключевых проблемы JSX, из-за которых автор решил изобрести свой велосипед. Неудобно получилось…


  1. DarthVictor
    17.11.2016 16:10
    +3

    Typescript прекрасно поддерживает TSX, при этом еще и проверку типов для props во время компиляции проводит.
    https://www.typescriptlang.org/docs/handbook/react-&-webpack.html


  1. shanhaichik
    17.11.2016 16:19
    +1

    Возможно мысль и благая, но лично меня смущает возможный просмотр листингов хотя бы среднего компонента в таком стиле. Какой-нибудь формочки, например.

    Во-первых, на мне кажется, что увеличивается возможность допустить ошибку
    Во-вторых, да же на среднем мониторе будет сложно это просматривать. Возможно кровотечение из глаз и поломку мозга


    1. Frozik
      17.11.2016 16:23

      Ага, чем-то мне это напоминает BEMJSON. Но большие листинги даже для jsx это зло и трудно для чтения.


      1. shanhaichik
        17.11.2016 16:26

        Согласен.
        Касательно BEMJSON, возможно, когда-то смотрел, но лично дело не имел.


  1. j_wayne
    17.11.2016 17:02

    Чем-то похож на elm-html. Со всеми вытекающими проблемами для верстальщиков…


  1. 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


  1. Moxa
    17.11.2016 18:16

    а riotjs не пробовали?


  1. seokirill
    17.11.2016 19:41

    используем тайпскрипт + jsx и не видим препятствий.

    p.s.
    неприемлЕм?