Comments 49
React это какой-то PHP для клиентской части. От чего ушли к тому пришли. Мешать код с шаблоном это полностью упоротое решение. Vue в этом отношении на голову выше.
Из раза в раз в каждой статье, где упомянут реакт, находится человек, который пишет такой комментарий.
Может, это традиция такая? :)
А вы не мешайте код с шаблоном, никто не заставляет.

Но как из банального массива вывести данные без цикла? Мне приятнее на js смотреть в плане циклов и прочего, чем на странные атрибуты в html. Вкусовщина, не более.
Но как из банального массива вывести данные без цикла?

XSLT :D

По поводу вкуса, мне лично нравится подход, который используется в blaze, но там усатые шаблоны, что может не для всех будет выглядеть эстетично. С другой стороны можно использовать pug и его нативные условия, итераций, переменные и т. д. Все никак не могу себя заставить дописать плагин, для компиляции pug в код шаблонов vue, именно не трансляцию в html и подключение в качестве результата шаблона, а трансляцию pug в код на js. То есть что бы работал код ниже:


ul
  //- people - берется из контекста vue,
  //- отслеживаются изменения массива и элементов,
  //- без использования дополнительных директив
  each name from people
    li= name

Вообще странным считаю, что никто еще такого не сделал, видел подобное опять же для метеора, со своими синтаксическими особенностями правда, что в прочем не мешало. И для react, трансляцию pug в jsx, но работает это достаточно странно, из-за ограничений при интерполяции.

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


module.exports = ({ foo, bar }) => pug`
  div= `${foo}-${bar}`.toUpperCase()
  //- или
  div #{`${foo}-${bar}`.toUpperCase()}
`

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


module.exports = ({ foo, bar }) => pug`
  div ${`${foo}-${bar}`.toUpperCase()}
`

В тестах к библиотеке есть еще пара примеров, когда интерполяция не работает. И выходит, что назначение таких выражений находится где-то между конструкцией #{...} в pug и ${...} в js, в этом я и вижу странность, но хотя не очень существенную.

Такого легко избежать, если использовать pug и не думать про интерполяцию. Почти все случаю возможны простым pug, а для других есть внутренняя интерполяция (#{}).

module.exports = ({ foo, bar }) => pug`
  div= (foo + '-' + bar).toUpperCase()
`

module.exports = ({ foo, bar }) => pug`
  div(
    attr=(foo + '-' + bar).toUpperCase()
  )
`


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

module.exports = ({ Component }) => pug`
  Component(firstProp="see you inside Component")
`


Больше примеров, как уйти от интерполяции: github.com/pugjs/babel-plugin-transform-react-pug#define-local-variables-and-use-javascript-in-attributes

Я понял про с ограничения в интерполяции, просто странно, что это негативная характеристика для pug в react.
Примеры из тестов — это ожидаемые фейлы.

Про то и речь, что этих фейлов не ожидаешь и из документации не следуют, что нужно их ожидать, но это отдельная тема. Чуть-чуть потыкав данную библиотеку, я на них сразу же наткнулся. Разобрался в чем суть и как это реализовано, реализация показалась странной: ни как в js, ни как в pug — отсюда и впечатления, не более того.


просто странно, что это негативная характеристика для pug в react

Согласен, этот момент мало-значимый. Видимо я так выразился под влиянием впечатлений.

Мне кажется вы лучше разбираетесь в поисках острых словечек, нежели истины или выбора. Я больше года топил за Angular, занимаясь бэкэндом. Ведь это фреймворк, это важно, очень важно, чтобы фронт был написан с использованием именно фреймворка! Но поработав с BackBone, например, и затем поработав (именно поработав, оба проекта были чужие) с React, а особенно с React+Redux, я резко изменил свою позицию. Есть отличный аргумент не в пользу реакта, «каждый проект — зоопарк технологий», но корни этого аргумента в том, что на практике реакт предоставляет гибкость, которая не снилась ни одному фреймворку.
«Вы просто не умеете его готовить».

В PHP в шаблонах нет ничего плохого. Все шаблонизаторы — лишь синтаксический сахар. Сказки про «ограничения для чистоты кода» годятся только для совсем уж новичков. На том же Twig можно так упороть шаблон, что PHP и не снилось.

С React та же история. Вас никто не заставляет мешать код с шаблоном. Просто вы никак не признаете, что в современном вебе JS-шаблон без кода никому не нужен.
В пхп с шаблонами как раз таки всё норм он для этого и придуман, но там весь остальной код написан на том же языке что и шаблоны.
  1. Мне кажется, подобным сравнительным статьям не хватает несколько примеров с задачами на порядок выше HelloWorld и с демонстрацией решения. У меня есть небольшой опыт разработки под React и нет опыта в Vue. И мне бы было бы искренне интересно посмотреть на каких конкретных примерах лучше один из фреймворков. Читая подобные статьи, лично у меня создается какое-то поверхностное представление. И я понимаю, что, чтобы действительно разобраться, мне нужно самому попробовать, но при этом хотелось бы получить эти знания из сравнительной статьи. А так получается, что это ещё одна статья из множества про поверхностное сравнение фреймворков только обновленная.
  2. Вот например, разговор про CSS. Неужели это действительно важная и сложная проблема? Работая с React, никогда не возникало никаких проблем в этом плане. Во Vue, я так понимаю, таких проблем тоже нет. Тогда зачем об этом говорить? Неужели в React это сделано настолько хуже и это должно меня мотивировать использовать Vue?
  3. Сравнение HTML-шаблонов и JSX. Об этом наверно уже было очень много разговоров. И одно и тоже. Вот лично у меня была проблема с JSX. Представим ситуацию, когда необходимо, чтобы HTML и CSS мог редактировать человек, без пересборки билда и запуска webpack dev сервера или его аналогов. Лично у меня не нашлось адекватного решения. А то что мне известно про фреймворки на основе HTML-шаблонов, в этом нет никаких проблем, т.к. HTML отделен от JS. React же по сути только JS, зная что JSX-это обертка над JS-кодом.
  4. Если сравнивать эту статью с её многочисленными аналогами, то она лучше только за счет своей актуальности. Она не хуже других. Но в абсолютном значении, мне все также необходимо изучить Vue, чтобы понять то, что мне бы хотелось понять после её прочтения.
По поводу пункта 3. dangerouslySetInnerHTML дал мне возможность отредактировать HTML страницы с бэкэнда, а для остального, уверен, править JS код руками контент-менеджера — плохое решение.
За React скажу, что можно долго обсуждать, что он не фреймворк, но после того как я начал использовать его с Redux, я полностью переосмыслил подход к написанию приложений с React. Сначала всё это кажется неоправданно сложно, но после того как разберешься все становится предельно просто, стройно и красиво.
3. Вы можете написанный JSX преобразовывать в обычный JS (React.createElement...) на сервере и затем подсовывать его в render() метод. Но честно, я не представляю когда такое может понадобиться.

Хотелось бы несколько раскрыть пункт про CSS, так как я его понял. И дополнить пункт про шаблонизацию, где я вообще не понял автора.


2) В примере в статье показывается, что для гарантированный изоляции стилей, применяемых к одному vue-компоненту, достаточно добавить директиву scoped в месте объявления блока со стилями. А если взять во внимание различные методологии, которые решают проблемы изоляции, именования и прочие, то эта директива может оказаться очень простым решением. Хотя и нельзя сказать, что в случае react подобное сделать сильно сложнее.


3) Так как в Vue есть поддержка JSX, это вообще наверное нельзя называть пунктом для сравнения, по крайней мере актуальным пунктом. Или должно быть явно сказано, что в одном случае счет 2, в другом — 1. Автор, конечно, забавно подметил, что не понимает тех кто в одном приложении будет пользоваться двумя подходами, как-будто кто-то заставляет, или как-будто это минус библиотеки, но при этом из текста явно не следует, что в Vue есть поддержка JSX. А так как в сравнении производительности приводится версия 2.x, где JSX есть, то я делаю вывод, что автор либо не особо изучал данный вопрос и понятия не имеет о чем пишет, либо как-то очень странно, художественно что ли, подходит к сравнению по этому пункту (хотя может тут и проблемы перевода, оригинал не читал).

5. Производительность. Как бы я, скорее всего, понял вторую часть этого раздела, не зная ничего про Vue и React: «В React-е необходимо много возиться с shouldComponentUpdate, а во Vue все работает из коробки.»
Но подождите? На самом деле в React достаточно наследовать класс от PureComponent вместо Component. И на моей практике этого всегда было достаточно, с точки зрения работы с методом shouldComponentUpdate. А если вы используете Redux, то и этого делать не нужно! Да там упомянули про PureComponent. Но для человека не работающего с React, может быть непонятно, что в этом нет проблем. А если это так, то зачем запутывать людей? Вы спросите, а почему это может запутать? Да потому что, когда ведётся сравнение, в детали обычно имеет смысл вдаваться только, когда объясняют разницу, а не сходство.
Суть той части в том, что и во Vue и в React проблем с настройкой производительности нет. Стоит ли об этом говорить, если это не отличие? Мне кажется, что нет. А может ли это запутать?…
Позвольте я немного перефразирую.

В Vue нужно возиться во все тех же случаях, что и в React с shouldComponentUpdate. Во всех остальных случаях все работает из коробки и там и там.
А вы думаете глубокое сравнение объектов всегда быстрее рендера в виртуальный дом?

Не в скорости дело, а в том, что можно долго искать почему компонент не перерендеривается когда точно знаешь, что значений свойства изменилось.

Ну, у Реакта я с таким ни разу не сталкивался, хотя не первый год с ним работаю.

Разве что в связке с MobX, но это немного другая история. Хотя тоже всего пару раз «попадал».
А как это у вас получается? Что в документации для Redux, что для React, строго необходимо менять все объекты по пути к изменённому свойству. Исходя из этого, независимо от того на какой глубине произошло изменение, корневой объект всегда будет новый, и поэтому всегда будет достаточно ленивого сравнения. Т.е. shouldComponentUpdate если все делать правильно никогда ненужно трогать, если происходит наследование от PureComponent. Считаю это справедливым для чистого React и React + Redux. Насчет React + MobX ничего не могу сказать.

Redux я сейчас не рассматриваю. При наследовании от PureComponent нужно отдельно следить, чтобы свойства и пр. не требовали глубокого сравнения. При наследовании от Component — не нужно, но, возможно, потребуется использовать shouldComponentUpdate для приемлемой скорости

Господа, я что-то пропустил? Когда React успел стать фреймворком?

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

Может тогда лучше использовать то определение, которое используют сами разработчики?
A JavaScript library for building user interfaces © reactjs.org
A declarative, efficient, and flexible JavaScript library for building user interfaces © github.com/facebook/react
Спасибо за статью, но не хватает более живых примеров из сложных проектов. Сам только изучаю React и параллельно посматриваю на Vue. Пока Vue мне нравится немного больше, по следующим пунктам:
  1. Документация, видимо потому-что к ней приложил руку Дэн Абрамов
  2. работа с анимацией, по крайне мере документация по ней сделана лучше, чем в React
  3. директивы v-if, v-else, v-show
,
Но т.к. пока изучаю React вчера столкнулся с таким решением скрытия элемента и как это реализовано в Vue мне нравится гораздо больше.
React
...
{
   errors.length > 0 ? Errors(id, errors) : null
}
...
const Errors = (id: string, errors: string[]) => {
    <ul className="mme-input__error">
        {
        ...
        }
    </ul>
}


Vue
    ...
    <ul v-if="errors.length > 0 " class="mme-input__error">
        {
           ...
        }
    </ul>
    ...



{errors.length > 0 ?
<ul className="mme-input__error">
...
</ul>
:null}


Я не думаю, что вам нужны все эти объявления из вашего примера. JSX — просто JS, вы можете писать код как вам угодно.

Вы, как и многие другие, приводите два примера с разным количеством действий и, соответственно, разным количеством кода. А потом удивляетесь, чего Реакт-код такой объемный :)

У меня вопросы скорее к vue коду, его читаемость мне кажется худшей из трёх вариантов. Что ul может не отображаться вообще становится заметно только после полного изучения его атрибутов, а условие может оказаться где-то за пределами экрана или просто затеряться среди десятка обычных атрибутов.

Опять же, зависит от разработчика.

Поидее, надо переносить все vue-атрибуты в начало, чтобы их было видно. А длина строки, по хорошему, должна ограничиваться IDE и переноситься на следующую строку. Тогда все будет видно и понятно.

Но в нашей реальности получается как получается :) А потом виноват фреймворк :)

Один из (основной?) переводов слова "фреймворк" — "рамки". Таки да, фреймворк виноват, что не загнал пользователя в жёсткие рамки :)

Я не писал про то, что фрейморк загнал нас в рамки :)

Я писал, что программист криворукий (никого конкретно не имею ввиду) и написал код, который усложняет восприятие и работу в целом :)

Грубо говоря, вот вам разница:

Фрейморк не виноват в этом случае.

Так если не загнал — значит виноват :) Должен был загнать, например кидать ошибку если атрибуты v-* не первые в списке атрибутов :)

Вот вам еще одно преимущество React.
Поскольку там JS, я могу настроить JSLint и вставить себе в колеса такие палки, что Vue и не снилось :)

P.S. Но вы можете подать идею в Vue, чтобы шаблоны не работали, если их атрибуты «забыты» в конце. Будет весело )
Я ни в коем случае не виню JSX и не грешу на длину кода, в данном примере я все же больше хотел сделать акцент на обязательный null в случае если не надо отображать элемент, либо можно без null но тогда придется обернуть в if(...){...} и это классно что у нас есть такая гибкость, лично для мне более лаконичным и приятным взгляду было бы использование директивы.

не нравится инлайновые условия, напишите себе хелпер.


function If({condition, children}) {
  return <>{children}</>
}

Получится даже лучше Vue, потому что одним if можно скрывать сразу несколько соседних элементов


<If condition={hideBlock}>
   <h1>Block title</h1>
   <p>Block content</p>
</If>

Прямо ангуляр какой-то получается :)


P.S. Но выглядит лучше чем с Vue и даже не из-за группировки, а из-за того, что if в самом начале конструкции.

Что-то похожее и на Vue можно:


<template v-if="ok">
  <h1>Заголовок</h1>
  <p>Абзац 1</p>
  <p>Абзац 2</p>
</template>

Поскольку v-if — это директива, она должна быть указана в одном конкретном теге. В данном случае template — это псевдоэлемент, который служит невидимой обёрткой и сам в результатах рендеринга не появляется.

Only those users with full accounts are able to leave comments. Log in, please.
Information
Founded

July 27, 2015

Location

Россия

Website

ruvds.com

Employees

11–30 человек

Registered

18 March 2016