Уроки React. Урок 1, Введение.

logo_og

Окунемся немного в прошлое и разберемся как вообще появился React, и зачем вообще нам нужны фреймворки. Вернемся лет на 10 назад к примеру, когда был только чистый JavaScript, зачастую он выполнял простейшие задачи, такие как валидация формы и.т.п. Ключевая концепция – это абстрагироваться от неких обыденных проблем, и решать более сложные, задачи. Так появились библиотеки и далее фреймворки. Т.е. абстрагируясь от того как должно меняться DOM дерево, был придуман Data Binding (two-way) и появились Angular, Backbone, Knockout, Ember. Т.е. идея была в том, чтобы максимально освободить разработчика от выполняя типовых задач и дать ему сконцентрироваться на поведении самого приложения. Data Binding (two-way Data Binding) в большинстве своем был реализован с помощью моделей –  MVС, MVVM. Этот паттерн пришел к нам из серверной разработки где используется уже много лет для построения API, сайтов. Мы разделяем наше приложение на модули, которые взаимодействуют между собой, выполняя свои узкоспециализированные задачи.

Model – модель

View – вид

Controller – контроллер

View общается с контроллером, Controller общается с моделями. Когда происходит какое-то взаимодействие во View, вы пишите к примеру, что пользователь нажал на кнопку, контроллер принимает запрос и сообщает моделям об изменении данных, модели меняют данные возвращают контроллеру, контроллер принимает и меняет View (его части по своему усмотрению в соответствие с действиями пользователя).

1

Есть дерево, некий View,

2

Есть данные пользователя живущие в модели: Name и Age. Контроллер знает, что от имени/возраста зависят указанные на картинке DOM NODEs и каждый раз когда что-то меняется мы следим за изменениями наших моделей, за изменениями данных. Нам необходимо знать, что именно поменялось. Как только в этой модели поменялось, например, Name или какое-то свойство, зависящее от Name, нам нужно пойти и поменять соответствующие DOM Nodes. Собственно, все вышеуказанные фреймворки это и делают. Ключевая идея MVС, MVVM Фреймворков в том, что они следят за изменениями данных, они знают какие элементы в реальном DOM от них зависят, и далее они идут и меняют их.

3

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

Поэтому с течением времени, с появлением сложных задач на Front-end появилась необходимость иметь архитектурные паттерны, которые больше подходят под клиентскую часть. Одним из первых кто решил отойти от концепции MVC стал React, привнеся свою концепцию виртуального DOM.
4

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

Дальше React делает div старого виртуального DOM и Div нового виртуального DOM и видит, что для того чтобы привести реальный DOM в актуальное состояние нужно изменить 2-3 элемента на страничке.

– Каждый раз, когда происходит изменения мы перестраиваем виртуальный DOM

– React сравнивает старый и новый виртуальный DOM, делает Div, понимает, что именно поменялось, далее идет и меняет реальный DOM только в том месте где необходимо. Таким образом пользователь постоянно видит актуальные состояния.

В этом и есть главная концепция. Главное отличие от MVC Фреймворков в том, что не важно какие данные поменялись, нас интересует сам факт изменения, чтобы далее перестроить виртуальный DOM.

Почему реальный DOM не так быстр? Он значительно более объемный чем виртуальный. Виртуальный хранит исключительно структуру. Что важно, так это то, что нас перестает волновать DOM как таковой, мы можем, оперируя компонентами строить любые структуры. DOM скорее отсылка к истории. Т.е. мы можем использовать такую структуру при создании native мобильного приложения где такого понятия как DOM нет. Там есть React view, а далее React делает из них Android, IOS Views или же рендерит все в строку если мы работаем на сервере.

Поговорим о Babel.

Babel это Transpiler, стандартный для работы с JSX React. Т.е. он позволят писать на es6 и транслировать его в es5 стандарт. Сама команда facebook отказалась от собственного решения и предложила пользоваться Babel.

Пример из песочницы с

https://babeljs.io

Код страницы:

транслируется из JSX

Отметим что в React нет templates, как в других Фреймворках. Раньше это реализовывалось добавлением в HTML какого-то сложного поведения. React подошел к проблеме с другой стороны. Понимая ограниченность HTML, разработчики решили дать JS возможность по созданию страниц – JSX. По сути JSX это и есть JavaScript. Это позволяет к примеру, отлавливать ошибки на этапе компиляции, а не когда клиент зайдет на страницу. Здесь нет такого понятия как шаблоны.

Никто не пишет проекты используя JSX, поэтому с самого начала нужно будет использовать Babel для transpiling.

Откройте учебный проект, вы можете скачать его здесь.

Взглянем на babelrc – это файл в котором необходимо описать некоторые преобразования, которые вы хотите, чтобы Babel выполнил над вашими файлами.

Первый из пресетов React превращает JSX в JS, далее подключаем es2015, stage-0 – подключение неких фич не вошедших в es6 (статические атрибуты классов, например).

Т.е. каждый файл будет преобразовываться в JS, ES6 в ES5, а на выходе мы получим, большой bundle.js который будет полностью на ES5.

https://webpack.github.io/

Посмотрите webpack.config

Web pack –  это программа позволяющая собрать большое количество модулей в один. Мы описываем здесь что есть исходный файл app.js из которого мы будем начинать нашу разработку который может импортировать разные модули и собирать их в один файл, для отправки на клиент. Перед тем как собирать файлы в один модуль он сначала пропустит их код через Babel. Все в Webpack описывается через Loaders. Также ознакомьтесь со скринкастом по нему:

https://www.youtube.com/playlist?list=PLDyvV36pndZHfBThhg4Z0822EEG9VGenn

Конечный код будет приложен в конце статьи, чтобы было легче разобраться. Исходным состоянием проекта является проект без JS файлов но с HTML файлом index.

Давайте создадим функцию, которая возвращает компонент. Запомните компоненты всегда называются с большой буквы. Наш назовем Article.js.

Теперь когда компонент описан нужно импортировать его в файле app.js

Хорошей практикой считается держать по одному файлу на компонент. Т.е. если у Вас 100 компонентов вы будете импортировать 100 компонентов.

Добавим такие строчки в этот же файл

В React и Webpack принято использовать NPM для зависимостей. (посмотрите JSON).

Прописываем в Console.

npm I react react-dom –S

Начиная с 14 версии разделили React и React/DOM. Так как появилось множество вещей, которые не зависят от DOM (работа библиотеке на клиенте, сервере, в мобильных приложениях).
В React DOM есть метод для того чтобы отобразить Ваш компонент. Пишем в том же файле.

Какой компонент (Article) и куда его положить. В файле index.html есть div container, в него мы и будем вставлять наш компонент.

В JSON есть webpack-dev-server который позволит запустить наше маленькое приложение с одним компонентом. Зайдем на localhost:8080

webpack-dev-server не собирает физически bundle.js – он хранит Ваши изменения в памяти.

Вернемся к файлу babelrc обратим внимание на:

“react-hmre”. 

Это hot-reloader. Он сохраняет состояния, и без всякой перезагрузки показывает все изменения.

Добавим в app.js в Article какие-нибудь переменные:

Т.е. взяли массив статей из fixtures.js и взяли первую статью. Тут используется новый для нас синтаксис JSX для нас.

{articles[0]} – скобки означают что здесь будет какое-то выражение, какая-то JS переменная. В нашем случае объект articles.

В JSX все что вы передадите таким образом article = {articles[0]}

Будет доступно в вашем компоненте через properties. (props) Оно придет к нам как аргументы.

Давайте сделаем компонент articlelist для отображения статей.

Изменим app.js следующим образом

В ArticleList.js делаем следующее:

На данный момент весь код в компоненте, написанном на JSX должен быть обернут в корневой элемент (div, например).

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

Используя map работаем с массивом статей в строчке 7, и превращаем его в массив компонентов. И отображаем его на 12 строчке. В 7 строчке пишем обязательно key, ассоциируя статьи с id чтобы React понимал при создании массива статей где какая, не смешивал их и т.п. Обычно используют ID, но это необязательно, так для этого подойдут любые неповторяющиеся ключи внутри одного массива. Не надо использовать index массивов в виде ключа. Здесь мы создали stateless компоненты, самые простые из возможных, которые получили данные, а затем выполнили их render. В идеале таких компонентов должно быть большинство. Но в реальной жизни необходимо менять и сохранять состояния этих компонентов. В этом случае нужно использовать более сложный синтаксис, такой как классы из ES6.

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

В строчке 1 файла Articles.js добавим {Component} на строчке 3 создадим класс, который наследуется от компонента React, где в самом простом случае мы должны описать метод render. Этот метод делает все тоже самое что мы и делали до этого, просто теперь мы описываем это  в нашем методе render. Теперь у нас уже нет аргументов, props входят в this при инициализации компонента props записываются в this. Далее мы будем писать так всегда, когда нам будут нужны более сложные компоненты.  Помимо props у нас есть состояния state (часть es7) на строке 4. Без es7 будет выглядеть как на строке 9. Строка 19 к примеру это тоже самое что и 18, но написана другим способом.

На строчках 21 и 22 пишем условия по отображению статей.

Добавим работу с состояниями по клику мыши. Для этого на строке 26 пишем

А на 32 строке описываем работу этой функции. Используем один из важнейших методов React setState. – он вызывает изменение DOM дерева. Эта операция асинхронная. Ваше виртуальное DOM дерево будет перестраиваться с того момента где произошел setState. Для проверки скачайте результаты нашего урока тут.

——————————————————————————————————————————

Домашнее задание – это реализация Comment List, – список комментариев к каждой статье который можно открывать /закрывать по клику на соответствующую ссылку. Текст ссылки должен меняться.

to-be-continued-series-8

We are looking forward to meeting you on our website soshace.com

About the author

Stay Informed

It's important to keep up
with industry - subscribe!

Stay Informed

Looks good!
Please enter the correct name.
Please enter the correct email.
Looks good!

Related articles

Уроки Express.js . Логгер, Конфигурация, Шаблонизация с EJS. Часть 2.

Favicon – это все connect Middleware, он смотрит, если url имеет вид favicon.ico, то он читает favicon и ...

3. Уроки Express.js. Шаблонизация с EJS: Layout, Block, Partials

В реальной жизни у нас обычно больше, чем один шаблон. Более того, если уж так ...

24.11.2016

Уроки Express.js. Основы и Middleware. Часть 2.

Всем привет! Давайте продолжим наш урок об основах Express и Middleware. Итог (добавим в ...

2 comments

Sign in

Forgot password?

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy

Password recovery

You can also try to

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy