Для новичка, экосистема вокруг React (как и фронтэнда в целом) может показаться запутанной. Этому есть несколько причин.

  • Изначально, React был нацелен на экспертов и ранних последователей
  • Facebook открывает исходный код только тех продуктов, которые использует сам, т.?е. не нацеленные на проекты-меньше-чем-Facebook
  • Огромное количество гайдов по React совершенно разной сложности


Здесь и далее, я предполагаю, что вы уже знакомы с HTML, CSS и JavaScript.



Зачем меня слушать?



Существует множество противоречивых советов по React. Зачем слушать меня?

Я работал в команде Facebook, которая разработала и опубликовала React. Теперь я работаю не в Facebook, а в небольшом стартапе, поэтому могу говорить с точки зрения своей текущей позиции, а не Facebook.



Как подойти к экосистеме React



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

Вы должны учиться в этом порядке, ничего не пропуская и не изучая две вещи параллельно:



Вам не нужно это все, чтобы быть продуктивным с React. Приступайте к следующему шагу, если у вас есть проблема, которую он решает.

Также, в React-сообществе есть несколько тем, которые являются «супер-современными практиками» («bleeding edge»). Эти темы интересны, но разбираться в них сложно, они менее популярны, чем темы выше, и не нужны для разработки большей части приложений:




Изучение самого React



Существует заблуждение, что чтобы начать работу с React, нужен огромный инструментарий. Но это не так. В официальной документации вы найдете copy-paste HTML шаблон, который достаточно сохранить в .html файле и сразу же начать работать. Для этого шага не нужен никакой инструментарий, и не стоит приниматься за него, пока вы не будете чувствовать себя комфортно с основами React.

Я также считаю, что самый простой способ выучить React, это официальный туториал.



Изучение npm



npm это менеджер пакетов Node.js и самый популярный способ для front-end разработчиков и дизайнеров делиться JavaScript кодом. Он включает модульную систему CommonJS и позволяет устанавливать инструменты командной строки, написанные JavaScript. Прочитайте эту статью, чтобы понять, почему и как используется CommonJS, или CommonJS Spec Wiki для большей информации о CommonJS API.

Большая часть компонентов, библиотек и инструментария в экосистеме React доступны как CommonJS модули и устанавливаются с помощью npm.



Изучение JavaScript сборщиков



По определенному количеству технических причин, использование CommonJS модулей (то есть всего в npm) невозможно нативно в браузере. Вам понадобится JavaScript “bundler” для сборки этих модулей в .js файлы, которые затем можно будет включить в страницу тегом <script>.

Примерами JavaScript сборщиков являются webpack и browserify. Они оба являются хорошим выбором, но я предпочитаю webpack, так как он имеет определенный набор фич, упрощающих разработку крупных приложений. Так как документация может показаться запутанной, у меня есть шаблон для быстрого старта, и я написал how-to гайд по webpack для более сложных кейсов.

Стоит запомнить: CommonJS использует функцию require() для импорта модулей, из-за чего некоторые пользователи начинают думать, что это нечто связанное с библиотекой require.js. По определенному количеству технических причин, я советую избегать require.js. Этот выбор не популярен в среде React.



Изучение ES6



Кроме JSX (который вы изучили в туториале React), вы могли заметить несколько забавных синтаксических конструкций в примерах. Это называется ES6, самая последняя версия JavaScript, с которой вы еще можете быть не знакомы. Из-за новизны, ES6 еще не полностью доступен в браузерах, но ваш сборщик может транслировать его в поддерживаемый JavaScript после определенной настройки.

Вам не обязательно знать ES6 для разработки на React, вы можете выучить его попутно.

Вы также могли слышать разговоры о том, что ES6-классы являются предпочитаемым способом создания компонентов React. Это не так. Большинство людей (включая Facebook) используют React.createClass().



Изучение роутинга



“Одностраничные приложения” (Single-page applications или SPA) — современная мода. Это веб-странички которые загружаются один раз, и, когда пользователь кликает по ссылке или кнопке, JavaScript, работающий на странице, обновляет адресную строку и контент, не перезагружая страницу целиком. Управление адресной строкой осуществляется router (роутером).

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

Не используйте роутер, если вы не создаете single-page application. Большинство проектов все равно начинают с маленьких компонентов внутри имеющегося большого приложения.



Изучение Flux



Скорее всего, вы слышали о Flux. Про него имеется *тонна* дезинформации в сети.

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

Компоненты React'а собраны в иерархию. В большинстве случаев, ваша модель данных также будет следовать этой иерархии. В этих ситуациях Flux не приносит особого выигрыша. Иногда, тем не менее, ваша модель данных не иерархична. Если ваши React компоненты получают props, которые кажутся «внешними», или у вас есть некоторое количество компонентов, которые начинают становиться сильно сложными, возможно вам стоит присмотреться к Flux.

Вы поймете, когда вам понадобится Flux. Если вы не уверены, что он вам нужен, то он вам не нужен.

Если вы решили использовать Flux, самой популярной и документированной Flux-библиотекой является Redux. Также есть *множество* альтернатив, возможно вы соблазнитесь попробовать их, но мой совет — использовать самую популярную.



Изучение инлайновых стилей



Пре-React, большинство людей использовали CSS-препроцессоры типа SASS для переиспользования стилей. React делает написание переиспользуемых компонентов простым, также упрощая и написание стилей. Многие из сообщества (включая меня) экспериментируют над тем, чтобы совсем избавиться от CSS.

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

Как только вы почувствуете то, как React работает, обратите внимание на альтернативные техники. Одна из популярных, это BEM. Я бы порекомендовал избавляться от CSS-препроцессора, так как React предоставляет более гибкий путь переиспользования стилей (через переиспользование компонентов) и ваш JavaScript-сборщик может генерировать гораздо более эффективные таблицы стилей для вас (доклад на эту тему на OSCON). Вместе с тем, React, как и любая другая JavaScript библиотека, сможет работать также хорошо с любым CSS-препроцессором.



Изучение рендера на стороне сервера



Серверный рендеринг часто называется «универсальным» или «изоморфным» JS. Это означает что вы можете взять ваши React-компоненты и отрендерить их в статический HTML на сервере. Это ускоряет первоначальную загрузку страницы, так как пользователю не нужно ждать, пока скачается весь JS, чтобы увидеть UI, а React, в свою очередь, может переиспользовать HTML, сгенерированный на сервере, не рендеря ничего на клиенте повторно.

Серверный рендеринг вам понадобится, если вы посчитаете, что первичный рендер страницы слишком медленный, или чтобы улучшить ранжирование в поисковиках. Да, Google индексирует контент, рендеренный на клиенте, но по состоянию на январь 2016 каждое измерение показывало, что это негативно влияет на ранжирование, потенциально из-за производительности рендера.

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



Изучение Immutable.js



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



Изучение Relay, Falcor и т. п.



Эти технологию помогают уменьшить количество AJAX-запросов. Они все еще являются относительно экспериментальными, так что если у вас нет проблем со слишком большим количеством AJAX запросов, вам не нужны Relay или Falcor.



UPD. Немного почищен перевод первых абзацев, спасибо vtambourine за правки
UPD2. Много мелких грамматических исправлений, спасибо wiygn

Комментарии (24)


  1. erlyvideo
    16.01.2016 21:45
    -31

    Херня.

    Пользуемся React, Routing. Всё остальное втопку, особенно Flux.


    1. RubaXa
      16.01.2016 22:12
      +37

      Ооо, эксперт, уровень «херня».


      1. erlyvideo
        17.01.2016 10:59
        -12

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


        1. RubaXa
          17.01.2016 16:56
          +5

          Если у вас есть проблемы или вопросы по Почте, просто напишите нам, или прямо мне на k.lebedev@corp.mail.ru, я всегда рад помочь. Ещё советую настроить postmaster, он способен устранить множество вопросов связанных с доставкой почты.


    1. alekciy
      17.01.2016 11:41

      Макс, а чем тебе Flux не угодил-то? Как я понимаю опыт есть, расскажи о своём кейсе.


      1. erlyvideo
        17.01.2016 12:30
        -3

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

        Flux — это плохой пример, потому что предлагает использование глобальных переменных и получение данных в обход всей иерархии. Это плохо сказывается и на тестировании и на изоляции и на всём остальном.

        Про Redux слышал, но не смотрел.

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


        1. turbo_exe
          17.01.2016 14:15
          +2

          согласен, то, что вы говорите имеет место в реакте. именно поэтому придумали smart & dumb components:
          medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.fz5k5xx7j


          1. erlyvideo
            17.01.2016 15:15
            -2

            Это всё понятно. Но это не отменяет того факта, что компоненты, которые работают с единой шиной не конфигурируются инстансом этой шины, а пользуются глобальными переменными.

            Это усложняет дальнейшее переиспользование кода.


        1. JCHouse
          18.01.2016 01:36
          +1

          Как раз таки Flux это НЕ глобальные переменные, а свойства определенного Store. А Redux это глобальные переменные, так как там один стор на все приложение. Никто вам не мешает использовать и колбеки и Flux одновременно, вот только с колбеками особой независимости компонентов не получается.


          1. Fesor
            18.01.2016 01:39
            +3

            А Redux это глобальные переменные, так как там один стор на все приложение

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

            собственно redux это реализация flux, просто в redux у нас единый источник правды и композиция редьюсеров, которые формируют новое состояние (а там у нас есть целоя гора возможностей как чего сделать), а flux — это просто принцип мол «юзайте event sourcing и все будет хорошо»


            1. darkwire
              18.01.2016 17:21

              Про Redux очень годные обучающие ролики от создателя egghead.io/series/getting-started-with-redux

              В первых роликах по сути Redux пишется небольшими кусочками с нуля, что практически сразу приводит к пониманию что-когда-зачем-почему. Очень советую для быстрого «въезда» в технологию, тем более, что серия по времени не очень большая, но супер полезная.


              1. darkwire
                18.01.2016 17:49

                Оказывается, на Хабре про это не писали :) Опубликовал… habrahabr.ru/post/275435


              1. Fesor
                18.01.2016 18:56
                +1

                Грег Янг идею Event Sourcing-а форсит с 2005-ого года примерно, а используется в том или ином виде уже не первый десяток лет. Ну так, к слову.


        1. Fesor
          18.01.2016 01:37
          +2

          Про Redux слышал, но не смотрел.


          подход redux-а как раз таки решает проблему flux-а которую вы описываете. Все состояние приложение хранится в одном месте, и спускается вниз разделяясь для каждого конкретного компонента. А там уже много всего можно придумать. Компоненты же поднимают ивенты о том что надо что-то сделать вверх, и так все проходит строго по циклу. Удобно, просто тестить, но на простых проектах — оверхэд.


          1. lega
            18.01.2016 15:30

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


            1. Fesor
              18.01.2016 16:46
              +1

              таких задач как бы нет, вот и все.

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

              Если компоненту вдруг понадобилось обновить состояние или поменять его — прокидываем в сервисы событие/действие, и далее ждем пока сверху у нас обновится состояние. Очень простая концепция которая невероятно упрощает махинации с UI.

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


              1. lega
                18.01.2016 18:11

                В компонент приходит уже готовый кусок состояния, который должен включать в себя имя пользователя. Ну то есть у нас есть одна жирная структура которая содержит в себе все.
                Вы же не предлагаете выкачивать всю БД на клиент, а значит вам нужно организовывать дополнительный код на (сервере и) клиенте который заботится о наличии данных именно для этого компонента.

                Например ангуляр, когда в компоненте понадобится вывести имя пользователя, я например в этой же компоненте просто укажу фильтр {{userId | getUserName}}. С Redux, получается, когда в этой компоненте нужно вывести имя, мне придется править какое-то третье место которое будет загружать доп. данные, т.е. появляется какая-то зависимость, что не хорошо.

                Ещё я получал такие ответы на этот вопрос от «сторонников» Реакта (не знаю что у них flux/redux/reflux или самопал):
                * Компонент сам загружает и хранит локальный кеш для этих данных.
                * Компонент сам загружает или отправляет ивент на загрузку, и доп. данные хранятся кешем в общем стейте.


                1. Fesor
                  18.01.2016 19:02
                  +1

                  Вы же не предлагаете выкачивать всю БД на клиент

                  Вы же не предлагаете выводить все данные на одной странице?

                  я например в этой же компоненте просто укажу фильтр


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

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

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


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


                  1. lega
                    18.01.2016 21:35

                    Вы же не предлагаете выводить все данные на одной странице?
                    Данные можно подгружать по требованию, в случае с Redux видимо нужно отправлять ивент на подгрузку данных и сохранение их в общий стейт.

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

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

                    но я все еще против загрузки данных из фильтров.
                    Фильтр берет данные из сервисов — все норм, и это удобно т.к. не нужно писать костыли в контроллере.

                    Вы переметнулись на сторону Реакта или используете redux/flux с Ангуляром?


                    1. Fesor
                      18.01.2016 22:16
                      +1

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


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

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

                      Вы переметнулись на сторону Реакта или используете redux/flux с Ангуляром?


                      как я уже отметил выше — только балуюсь с редаксом, в продакшене у меня просто схожая концепция (прокидывание данных из ресолверов роутера вниз в компоненты). Ангуляр на реакт заменять не планирую, уж сильно мне нравятся декларативные шаблоны вместо операций с виртуальным домом. Мне банально удобнее это все тестить и вообще как-то веселее.

                      Вообще вы хорошие вопросы задаете, надо придумать кейсов. У меня пока все хорошо и все разделено тупо за счет роутера.


                      1. lega
                        18.01.2016 22:34

                        Пишите статью, думаю многим может быть интересно :)


        1. iKBAHT
          18.01.2016 02:09
          +2

          Flux — это плохой пример, потому что предлагает использование глобальных переменных

          Что? В идее Flux ни чего не сказано о глобальных переменных.


  1. SerCe
    16.01.2016 23:16
    +4

    А я вот посоветую хотя бы посмотреть в сторону clojurescript + reagent, код получается чертовски простым и прекрасным (хотя для незнакомых с lisp непривычным поначалу)!
    React по сути своей очень функционален и его пересечение с функциональным clojure дает поразительный результат. Надеюсь, когда-нибудь соберусь таки написать об этом обзорную статью на хабр.


    1. borNfree
      17.01.2016 10:19
      +8

      Было бы интересно, так что собирайтесь быстрее