Обновить
Комментарии 46
Из пункта 2 посмотрел пример — это вообще не ангуляровский подход, Там нужен ng-repeat + filter внутри ng-repeat. А не какие то циклы вручную и.т.п.
То есть я хотел сказать, что если сравниваете, то хотя бы ознакомтесь в предметом сравнения, а то получается как в анекдоте:

Встречаются два еврея:

— Слышал я «Битлз», не понравилось. Картавят, фальшивят… Что людям в них нравится?!

— А где ты их слышал?

— Да мне Мойша напел…


По поводу reactjs: долгие годы прошли у программистов чтобы понять что «логика + отображение» в одном месте => тяжело поддерживать
и react наступает на те же самые грабли, что вы об этом думаете?
По поводу reactjs: долгие годы прошли у программистов чтобы понять что «логика + отображение» в одном месте => тяжело поддерживать
и react наступает на те же самые грабли, что вы об этом думаете?

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

Если хотите узнать как действительно нужно работать с логикой, то почитайте про Flux.

Я бы сказал что примеры сверху даже вредны, так как совершенно не раскрывают что же делать с данными, чтоб код не превратился в кашу.
Точно. Многие думают что JS — логика по определению, HTML — презентация. Но в случае с React — только JS используется для презентации, как более экспрессивный язык. JSX — всего лишь опциональная обертка, немного упрощающая работу. Смешивания нигде нет, React отображает, а логику можно (и нужно) располагать в другом месте. Конечно, оно может возникнуть в результате применения плохих практик, но так, в общем-то, в любом фреймворке.
React это просто отображение состояния, а не бизнес-логика
То есть это получается шаблонизатор, тем более я не понимаю зачем его с ангуляром сравнивать.

Если хотите узнать как действительно нужно работать с логикой, то почитайте про Flux.
Прочитал про flux, понял почему генерируют размётку из JS (чтобы более производительно рендерить, но это не сильно распростанённая проблема, текущие фреймворки вполне производительны). Те же представители фейсбука рассказывающие про тысячи комментариев на странице их динамически подгружают, то есть это любой фреймворк выведет без проблем с производительностью. Но всё же javascript не подходит для шаблонизации, его код легко поломать и для модификации требуется более высокооплачиваемый специалист, то есть «сделать кнопку овальной и с картинкой» кроссбраузерно, дешевле и быстрее верстальщику, нежели серьёзному фронтенд разработчику.

И про работу слогикой:
на мой взгляд flux ничего нового не привнёс в плане архитектуры,
контроллеры назвали «action»,
модели назвали «store»,
а вьюшки остались «views», только в отличие от того же ангуляра, простейшие вещи в реакте делать нелегко.
То есть это получается шаблонизатор, тем более я не понимаю зачем его с ангуляром сравнивать.

Вы сильно лукавите, когда говорите что это «получается шаблонизатор». Нет, React берет на себе решение большего количества задач. Я тоже не в курсе с какой целью его сравнивать с ангуляром и не понял какую именно мысль вы пытались донести.

Что касается сложности вёрстки, так эта проблема надумана и существует в рамках конкретных кейсов, а не в общем случае.

на мой взгляд flux ничего нового не привнёс в плане архитектуры,

Flux это не что-то новое, а ответ на вашу реплику:
«логика + отображение» в одном месте => тяжело поддерживать
и react наступает на те же самые грабли
Вы сильно лукавите, когда говорите что это «получается шаблонизатор».
Я не лукавлю, просто говорю о том как понимаю, если вы объясните или скажете где посмотреть что я понял неверно, я буду вам очень благодарен.
Как самая близкая ассоциация с ангуляром — это его директивы в сравнении с reactjs, то есть компонент состоящий из контроллера + отображения?

Что касается сложности вёрстки, так эта проблема надумана и существует в рамках конкретных кейсов, а не в общем случае.

В джаваскрипт надо лазить чтобы вёрстку поправить (класс, например, добавить какому либо элементу или завраппить элемент)?
В джаваскрипт надо лазить чтобы вёрстку поправить (класс, например, добавить какому либо элементу или завраппить элемент)?

Смотря как у вас проект устроен. Я видел реализацию как в функцию render из reactjs импортировали шаблоны из других файлов. В этом случае всё выглядит так словно шаблоны лежат отдельно и написаны на близком к html языку (jsx).
К сожалению я не смогу правильно сравнить ангуляр и реакт, т.к. не очень хорошо знаю ангуляр.
Ну можно с директивами ангуляра и их взаимодействием поверхностно ознакомится в этих 2х видео за 10 минут:
https://egghead.io/lessons/angularjs-first-directive
https://egghead.io/lessons/angularjs-directive-to-directive-communication

P.S. Сайт, классный, кстати, рекомендую там и другие видео посмотреть, там не только про ангуляр. Про react тоже выложили 26 видео, я в течение недельки посмотрю, углублюсь.
Компоненты реакта, кстати, похожи на директивы ангуляра. Но в отличие от ангуляра, они не требуют даже двух минут видео на понимание :)

Например надо тебе абстрактный список как угодно отрисованных элементов. Возможно потом сортировку какую приделать к нему, или банальную рамку снаружи. Делаешь:
var myList = react.createClass({ 
   render: function() { 
      return dom.div({}, this.props.items.map(this.props.renderItem))
   }
)


и потом используешь в другом компоненте:
var anotherComponent = react.createClass({
  render: function() {
    return dom.div({}, myList({
      items: [1,2,3], // передаем данные на отрисовку 
      renderItem: function(item) { return dom.span({}, item.toString()); } // передаем функцию отрисовки одного элемента
    }))
  }
})
Плохой пример, потому что в ангуляре это уже написано (и сортировка тоже). И повторное использование в директивах там понятнее.
По аналогии с вашим примером, для добавления рамки снаружи я просто в вёрстке перенесу ng-repeat на уровень выше.
И будет выглядеть вместо:
<div>
   <span ng-repeat="item in items">{{item}}</span>
</div>

Вот так:
<div>
  <div ng-repeat="item in items"> 
    <span>{{item}}</span>
  </div>
</div>


А если нужен просто обрамляющий div я его добавлю не думая о директивах и angularjs:
<div>
   <div>
     <span ng-repeat="item in items">{{item}}</span>
   </div>
</div>

И это сможет сделать самостоятельно верстальщик, без понимания что там за «классы React» и «неоднозначного синтаксиса javascript с его особенностями».

P.S. вообще сравните как выглядит ваш пример и то что я написал.
P.P.S. мало того для такой простой задачи в ангуляре вообще не нужны никакие самостоятельно поддерживаемые js файлы, что есть большой плюс.
Т.е. ты мне привел пример одноразового использования, а я — полноценного компонента.

Попробуй дальше свой пример масштабировать, например добавить туда фильтрацию элементов и кнопку с возможностью добавлять еще элементы. Причем реюзабельно, т.е. представь что список у тебя в пяти местах уже используется.

Тебе придется делать директиву. А это уже и JS-код, и шаблон где-то в другом файле. И нужно во всех местах где используется поменять ng-repeat на свою директиву.

И да, я согласен что html с директивами, в относительно простых случаях более понятен, особенно верстальщикам. Но если верстальщих и фронтенд-разработчик — одно лицо, а логика во view хитрая — реакт выигрывает.
Напишу своё видение React-а.

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

Вот, упрощённый, пример о чем я говорю:

Window = React.createClass
reload: (cb)-> @forceUpdate(cb) 
render: ->
@transferPropsTo(Document())

Document = React.createClass
render: -> @transferPropsTo(Html)

Html = React.createClass
render: -> React.DOM.div(null, Head, Body)


# etc.

window = React.renderComponent(new Window({global: this}), document.body);

# now you write your business logic
# and when model changed you simple reload all page

user.on('change', window.reload);


Такой подход, когда вам не надо хранить состояние представления,
позволяет вам писать в функциональном стиле.

React можно использовать с Angular, Ember и др. framework-ами. React решает
конкретную проблему — синхронизация состояния приложения с представлением, и вроде справляется с этим
не плохо.

Есть проблемы с инфраструктурой jshint, подсветка, completion и др., но решаемые так или иначе.

Сам активно изучаю React.
React довольно низкоуровневый, что может быстро привести к не читаемому коду.
Количество Best/Bads Practice не так много, поэтому приходится набивать `шишки`.
Для себя завел небольшой gist где собираю все, что показалось интересным, по React-у. Возможно найдете что-то полезное.
(Для сравнения, смотрите нашу версию с AngularJS).
Там нужен ng-repeat + filter внутри ng-repeat.

Для сравнения сделал версию на AngularLight (на AngularJS будет так же).
Хотя не понятно что там сравнивать…
Так и есть, просто там фильтр полноценный дополнительный(даже не фильтрующую функцию) в примере по ссылке написали и получилось не менее громоздко как в примере с reactjs.
>По поводу reactjs: долгие годы прошли у программистов чтобы понять что «логика + отображение» в одном месте => тяжело поддерживать
и react наступает на те же самые грабли, что вы об этом думаете?

Долгие годы ушли у программистов, чтобы попытаться построить рабочий процесс с разделением на «фронтэнд-программист» и «дизайнер-верстальщик». По факту оно даже заработало — для типовых сайтов-магазинов.

Но когда UI-логика действительно сложная — проще верстать тому же программисту, который пишет фронтенд-логику. И вот тогда получается что программисты, умеющие писать код на гибких и мощных языках, вынуждены писать на шаблонизаторе, где есть только if и foreach. Причем часто — чисто из религиозных побуждений.

React ушел от идеи «тупого шаблонизатора», и через это пришел весь его кайф. Например можно передавать функцию для рендера ячейки внутрь компонента таблицы. Передавать один компонент как параметр в другой. Или функцию, которая вернет class для строки по данным. Или там хелперы делать какие угодно. Этот весь код можно рефакторить, можно писать на typescript и иметь всякий автокомплит и compile-time контроль типов. Можно к нему писать тесты. И так далее.

И второй момент — уходит необходимость в т.н. view model. В случае с тупыми шаблонизаторами, между «контроллером» и «вьюхой» требуется еще одна прослойка, в которую умный «контроллер» положит все что не может расчитать глупый шаблонизатор. В react это не требуется — компонент может совершенно непринужденно обрабатывать входные данные.
И второй момент — уходит необходимость в т.н. view model. В случае с тупыми шаблонизаторами, между «контроллером» и «вьюхой» требуется еще одна прослойка, в которую умный «контроллер» положит все что не может расчитать глупый шаблонизатор. В react это не требуется — компонент может совершенно непринужденно обрабатывать входные данные.
На самом деле и в react эта прослойка тоже будет, потому что для отображения данных в компоненте их нужно будет, как минимум, получить извне. Опять же в статье его сравнивают с angularjs, а у него такой проблемы нет, ибо у него есть директивы которые умеют всё что умеет react, даже больше.

Проблема React в том, что для дополнительной производительности(которая неоправдана даже в видео товарищей из facebook, то есть всё что они там делают можно делать на любом фреймворке и будет быстро работать) добавили дополнительный слой абстракции между JS и вёрсткой и эта прослойка более неприятная чем переменные во вьюшках, потому что уже нельзя просто открыть файл и поправить вёрстку, теперь надо открыть файл в IDE, найти где лежит нужный класс, понять как, что и откуда наследуется и выводиться и потом уже поправить, когда есть много маленьких исправлений, это очень неприятный процесс. Особенно потому что первоначально смотришь на вёрстку, а править надо некоторые JS-абстракции.
>На самом деле и в react эта прослойка тоже будет

ViewModel все равно нужно, да. Но в нем не нужны поля вроде пред-вычислений, которые сложно сделать непосредственно во view. Типа сходить в словарик за значением по ключу, сделать if на пять вариантов, сгруппировать элементы массива — все это делается прямо в компоненте. Т.е. модель на входе react может быть более легкая и близкая к предметной области.

>Проблема React в том, что для дополнительной производительности… добавили дополнительный слой абстракции

Реакт наоборот убирает слой абстракции — который про DSL а-ля html с директивами, который переводит JS-объекты в DOM.

>… теперь надо открыть файл в IDE, найти где лежит нужный класс…

Дополнительный уровень абстракции — это всегда палка о двух концах. Оно в простых случаях добавляет геммороя, но на больших объемах и большей сложности кода отбивается за счет большего реюза, всяких рефакторингов, линтерах, find usages, и т.п.
Я понимаю, что это перевод, но как можно называть библиотеку фреймворком? В документации все четко расписано:
React is a JavaScript library for creating user interfaces by Facebook and Instagram. Many people choose to think of React as the V in MVC.

Поэтому сравнивать его с Angular.js и Ember.js уже не верно. Это все равно, что написать, что jQuery как фреймворк проще, чем Angular.js и Ember.js :)
Да, ставить React наряду с angular немного не верно, но тем не менее, большинство называет его фреймворком.
Ну дак может уже пора называть его правильно?
Если большинство называет Java как «Ява», то это значит, что Jazz теперь называется «Язь» :)

P.S. Большинство, которое не читает официальную документацию?

Блин, народ, я переводчик, поэтому перевожу как написано. Может мне вообще React framework переводить, как библиотека Реагирования? За что минусы то? Я согласен, что это скорее библиотека, но я не могу переводить, как мне вздумается.
Но если статья не верная, то зачем её переводить? Возмите за основу оригинал и переработайте. Мы вроде тут оцениваем не качество перевода, а ценность материала статьи.
Статья была рекомендована в списке полезностей и интересностей для веб-разработчика, вот и перевел. Я бы не сказал, что эта статья плохая, она для тех, кто хочет ознакомиться с основами react. Это, кстати, подтверждает рейтинг статьи.
И кстати, скоро переведу более углубленный цикл статей по React, это будет уже для ознакомившихся читателей. Всему свое время;)
Мне кажется, что в таких случаях стоит в начале статьи делать вступление от переводчика, в котором бы оговаривались такие моменты.
Вы часто такое в переводах видите?
Реже, чем хотелось бы.
render: function() {

        var self = this;

        return (
            <div>
                <ul>{ this.props.items.map(function(m, index){
        
                    var style = '';
        
                    if(self.state.focused == index){
                        style = 'focused';
                    }

                    return <li className={style} onClick={self.clicked.bind(self, index)}>{m}</li>;
        
                }) }


image

Мне кажется они переборщили с перемешиванием js и html.
Да, примеры, мягко говоря, не ахти.
Перемешано, все что только можно перемешать.
Там можно писать на JS, я так и делаю. Данный пример на typescript и со штатным хелпером cx для слепливания class-ов, я бы написал как-то так:
var items = this.props.items.map((text, index) => 
     dom.li({ 
        className: cx({ focused: self.state.focused == index }),
        onClick: this.clicked.bind(self, index)
     }, text)
)
return dom.div({}, dom.ul({}, items))
А за счёт чего работает setInterval(this.tick, 50); — кто обеспечивает передачу корректного this при вызове функции tick()? React/JSX что, подменяют window.setInterval или форсируют Function.prototype.bind() для всех методов создаваемого класса/компонента?
Похоже, что так. React automatically binds component methods to each instance so there’s no need to worry about maintaining scope — выдержка из статьи, которую я как-раз перевожу.
При инстанцировании класса компоненты все методы прибиндиваются.
Кода нужно гораздо меньше, если писать на LiveScript:
red-badger.com/blog/2014/05/27/using-livescript-with-react/

Одновременно с этим отпадает надобность использовать JSX, и получается интересный, JADE-подобный синтаксис, который легко читается:

product-row = React.create-class do
  render: ->
    tr null,
      td null,
        span do
          if @props.product.stocked
            style:
              color: 'red'
          @props.product.name
      td null, @props.product.price
Да, напрашивается там безскобочный синтаксис на отступах — тот же coffeescript должен тоже норм зайти. А то в JS слишком много скобок выходит. Впрочем, я пишу на typescript — в целом нормально получается, там как минимум есть лямбды с замыканием this, без них тоже печально.
Товарищи! Пожалуйста, будьте грамотными. Не пишите, как ПТУшники или курицы с лапами
Автор перевода!..
Что конкретно вам не нравится? Такой же комментарий можно написать под любым постом, а вы пожалуйста обоснуйте, и подскажите, что не так, чтобы я мог исправить.
Навскидку
Вы можете заключить любое JavaScript выражение между скобок {}, при создании компонента
Мы, снова и снова, узнаем, что люди терпеть не могут ожидание.
Спасибо, исправил. Дело в том, что при чтении своего перевода некоторые предложения воспринимаются на автоматизме, даже если они очень корявые. В таком случае помогает взгляд со стороны.
Остался один вопрос, а что если нужно будет рендерить не в конкретное место на HTML странице, а во множество?
Например, если есть HTML страница, в которой в разных частях находятся баннеры, например, в элементе <AdvBox />.
Манипуляции с document.querySelectorAll в React.renderComponent не дали положительного результата, а если оставить document.body, то перезаписывается весь body полностью.
Примеры в jsfiddle больше не работают, или я что-то не так делаю? При открытии их на вкладке "результат" просто пустая страница.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.