Advertisement
  1. Code
  2. JavaScript

Створення застосунків для сумісного використання за допомогою PubNub, React.js і ES6

Scroll to top
Read Time: 13 min

Ukrainian (українська мова) translation by Nadia Gonzales (you can also view the original English article)

В моїх попередніх посібниках я показала, як створювати прототип приладів, що відповідають концепції IoT (* Internet of Things – Інтернет речей; концепція мережі, що складається із взаємозв'язаних фізичних пристроїв, які мають вбудовані датчики, а також програмне забезпечення, що дозволяє здійснювати передачу і обмін даними між фізичним світом і комп'ютерними системами, за допомогою використання стандартних протоколів зв'язку. Тут і надалі примітка перекладача.), і зробила візуалізацію даних, отриманих від датчиків обладнання, за допомогою Мережі потоку даних (* DSN – Data Stream Network) PubNub (* швидко працююча система обміну повідомленнями між будь-якими пристроями та платформами).  У цбому посібнику я збираюся показати, як використовівати PubNub для створення веб-застосувань для сумісного використання, що працює в режим реального часу, за допомогою React.js, що дозволяє вам дуже ефективно маніпулювати DOM (* Об'єктна модель документа), і наступного покоління JavaScript, ES6 (специфікація ECMAScript 6).

PubNub Reactjs Stickie Web AppPubNub Reactjs Stickie Web AppPubNub Reactjs Stickie Web App

Онлайн демоверсія: Записки-наклейки для сумісного використання

Я створила дві версії того ж самого додатка Stickie Note (* для створення стікерів для заміток): у першій, що розташована на CodePen, використовуються версії React (* React.js; бібліотека  JavaScript для створення користувальницьких інтерфейсів) з CDN (* content delivery network – мережа доставки (розповсюдження) контенту), а друга розташована на GitHub, і в ній для підключення React використовується пакетний менеджер.  У цьому посібнику я використовую «легкий» варіант останньої версії.  Ми пройдемося по процесу створення додатка, використовуючи всі фішки: npm, webpack, Babel (* компілятор для JavaScript, а точніше транcпілятор) для JSX (* розширення синтаксису для JavaScript) та ES6!

Попередні підготування

Для цього посібника вам будуть необхідні:

  • базове розуміння React
  • практичні знання пакетного менеджера npm для завантаження, встановлення та керування залежностями
  • практичні знання збирача пакетів webpack (* збирач пакетів для JavaScript з відкритим початковим кодом), за допомогою якого робиться укомплектування ресурсів JavaScript та інших ресурсів для браузера (він рацює подібно до grunt или gulp)
  • встановлені на вашому комп'ютері Node і npm

У цьому посібнику не даються початкові знання по React.   Проте ви можете дізнатися про React більше з інших чудових посібників на Envato Tuts+.

Що ми збираємося створювати

Зараз ми збираємося створити простий веб-додаток за допомогою PubNub.  PubNub – мережа потоку даних (* DSN – Data Stream Network), що надає глобальну інфраструктуру (* основоположна сукупність компонентів, об'єднана в систему) за допомогою якої можна доволі просто створювати та масштабувати застосунки, що працюють у режимі реального часу, та пристрої IoT.  У цьому посібнику ми створимо «стікери для заміток» сумісного використання.  Ось як виглядає послідовність взаємодії користувача із застосуванням.

  1. Користувач входить до застосування.
  2. Тільки-но користувач вводить ім'я, застосування отримує останні 50 заміток, якщо вони є.
  3. Користувач набирає повідомлення на стікері та натискає клавішу вводу для відправлення.
  4. Нова замітка з'являється разом із іншими на сторнці вашого браузера, а також на сторінках інших браузерів усіх користувачів, що знаходяться в той момент онлайн.

Тепер давайте почнемо!

Встановлення пакетів

В папці вашого додатка виконайте npm init для налаштування вашого файлу package.json, і потім встановіть ці модулі.

Встановіть збирач пакетів webpack, що компілює, об'єднує, здійснює мініфікацію та стиснення статичних ресурсів для клієнтської частни додатка.

$ npm install webpack --save-dev

Встановіть webpack-dev-server для запуску локального сервера:
$ npm install webpack-dev-server --save-dev

Встановіть React, React DOM і розширення CSS для реалізації анімації: 
$ npm install react react-dom react-addons-css-transition-group --save

Встановіть Babel для використання JSX і ES6.  Ми збираємося писати код ES6 (ES 2015) за допомогою Babel: 
$ sudo npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save

Встановіть PubNub для забезпечення комунікації в режимі реального часу: 
$ npm install pubnub --save

Налаштоваємо структуру додатка та веб-сервера

Створіть структуру додатка подібною до наступної:

1
├── /app
2
│   ├── app.jsx
3
│   ├── stickie.jsx
4
│   ├── stickieList.jsx
5
├── /dist
6
├── /css
7
├── /images
8
├── /node_modules
9
├── index.html
10
├── package.json
11
└── webpack.config.js

Та налаштуйте webpack.config.js:

1
var webpack = require('webpack');
2
module.exports = {
3
  entry: './app/app.jsx',
4
  output: {path: './dist', filename: 'bundle.js'},
5
  watch: true,
6
  module: {...}
7
}

Ознайомтеся з повним конфігураційним файлом у репозиторії GitHub.

Власне, ми визначаємо точку входу додатка (файл вищого рівня) та розташування для файлу вихідних даних, де усі ваші файли js (и .jsx)  будуть об'єднані в один після виконання команди webpack.  Також за допомогою визначення watch: true ви гарантуєте, що webpack буде відслідковувати зміни ваших файлів та відтворить результівний файл автоматично.

Створення файлу index.html

Підключіть скрипт bundle.js до вашого файлу  index.html:

1
<!DOCTYPE html>
2
<html>
3
  <head>
4
    <meta charset="utf-8">
5
    <title>Collaborative Stickies</title>
6
    <link rel="stylesheet" href="css/style.css" />
7
  </head>
8
  <body>
9
    <section id="container"></section>
10
    <script src="dist/bundle.js"></script>
11
  </body>
12
</html>

Також зверніть увагу на елемент із id=”container” в тілі. Саме тут буде розташовуватися ваш додаток React.

Запуск Webpack Dev Server

Ви можете запустити ваш сервер для розробки за допомогою команди: 
$ ./node_modules/.bin/webpack-dev-server

Або ви можете налаштувати його запуск у вашому package.json за допомогою рядка: 

1
"scripts": {
2
  "start": "webpack-dev-server"
3
},

таким чином, що ви зможете запустити сервер за допомогою команди npm start 

Перейдіть у вашому браузері на сторінку http://localhost:8080/webpack-dev-server/, і ви повинні будете там побачити ваш запущений додаток (поки що тільки порожня сторінка HTML).

Створення компонентів React за допомогою ES6

Відкрийте новий файл app.jsx в папці app, який ви вказали в якості точки входу додатка у вашому webpack.config.js.  Як ви могли помітити по розширенню імені файлу, ми збираємося використовувати JSX.

Для початку імпортуйте модулі та файли, що необхідні для app.jsx: 

1
import React from 'react';
2
import ReactDOM from 'react-dom';
3
import StickieList from './stickieList';
4
import 'pubnub';

Оператор import, що з'явився в ES6, використовується для імпорту функцій, об'єктів чи примітивів, що були експортовані із зовнішнього модуля або скрипта.

Далі визначаємо клас CollabStickies, що поширює клас React.Component за допомогою об'явлення класу згідно зі стандартом ES6.  Це – еквівалент для React.createClass згідно зі стандартом ES5:

1
class CollabStickies extends React.Component {
2
  constructor(props) {
3
    super(props);
4
    this.state = {
5
      stickieList: []
6
    }
7
  }
8
9
  componentWillMount() {
10
     // will explain later

11
  }
12
...
13
  render() {
14
    return (
15
      <div>
16
        <StickieWritable username={this.props.username} color={this.props.color} />

17
        <StickieList stickieList={this.state.stickieList} />

18
      </div>

19
    );
20
  }
21
}

У конструкторі ви встановлюєте початковий стан цих мінливих даних – масиву stickieList.  Ми будемо оновлювати масив кожного разу при отриманні нової замітки за допомогою this.setState().

В функції render використовуємо JSX для визначення шаблоноподібних елементів віртуального DOM.  В нашому випадку підключаються компоненти StickieWritable і StickieList.  Ви можете передавати мінливі props (* реквізити) та   states (* стани) компонентам для використання.  Ми визначимо їх пізніше.

При створенні додатка Babel здійсне транспіляцію всього коду на ES6 та коду на JSX до ES5, який браузери можуть добре виконати.

Рендеринг вузла DOM разом із прив'язаними даними

За допомогою ReactDOM.render(),  що поставляється разом із пакетом react-dom, виконайте відтворення компонента CollabStickies у вузлі DOM у вашому HTML.

1
ReactDOM.render(
2
  <CollabStickies username={username} color={color} />,

3
  document.getElementById('container')
4
);

Тут ви помітили props username і color.  Ці дані використовуються для компонента CollabStickies та пердаються його дочірнім компонентам.

Значення повинні бути отримані після входу користувача; проте, для спрощення додатка для нашого прикладу давайте використовувати просто window.prompt() для отримання username і потім задамо випадковий колір, коли додаток завантажено. 

1
var username = window.prompt('Your name');
2
3
const colors = ['yellow', 'pink', 'green', 'blue', 'purple'];
4
var color = colors[~~(Math.random() * colors.length)];
The localhost Server asking for your nameThe localhost Server asking for your nameThe localhost Server asking for your name

Хоча я використовую вбудоване до браузера вікно підказки, у дійсності я раджу створити інший компонент UI для реалізації можливості входу чи використовувати сторонні компоненти вікна діалогу.  Існує багато готових компонентів, наприклад: Elemental UI’s Modal і Material UI’s Dialog.

Використання  для реалізації можливості співробітництва

Тепер ми збираємося використовувати PubNub для реалізації можливості сумісного використання.

PubNub – глобально розповсюджена мережа потоку даних, що дозволяє вам легко створювати додатки, що працюють в режимі реального часу.  Головна можливість, яку надає PubNub, – відправлення та отримання даних між багатьма користувачами одночасно.

У нашому додатку кожний, хто «увійшов» до додатку, може залишити повідомлення на стікері та поділитися ним із іншими користувачами.

How PubNub WorksHow PubNub WorksHow PubNub Works

Для використання PubNub у вашому додатку впевніться, що модуль pubnub встановлено та імпортовано у верхній частині вашого додатка.Ініціалізація PubNub

Ініціалізація PubNub

Для початку вам необхідно ініціалізувати PubNub для створення зразка її об'єкту.  Вам необхідні ваші ключі API для нінціалізації, так що, будь ласка, зареєструйтесь у PubNub для їх отримання.

1
const publish_key =  'pub-c-1d17120...'; // your pub key

2
const subscribe_key  = 'sub-c-85bdc...'; // your sub key

3
4
const pubnub = require('pubnub').init({                         
5
  publish_key   : publish_key,
6
  subscribe_key : subscribe_key,
7
  ssl: true,
8
  uuid: username
9
});
10
11
const channel = 'stickie-notes';

Тут ви присвоюєте username, отриманий після процесу «входу» як uuid (унікальний ідентифікатор).  (У нашому прикладі ми використовуємо у якості uuid будь-який рядок, введений користувачем, але в реальності вам необхідна буде професійна система для «входу», щоб кожний uuid був у дійсності унікальним, без повторень!)

Також зверніть увагу, що я використовую об'явлення констант у стилі ES6 за допомогою const замість var для цих глобальних значень констант.  У ES6 const діє в якості змінної тільки для зчитування та представляє собою постійне посилання на значення.   Далі ви побачите також недавно представлену let – локальну змінну з блочною областю видимості.

Підписка на повідомлення

Для створення додатка для обміну записками ми збираємося використовувати метод publish() PubNub для відправлення ваших повідомлень кому завгодно, тоді як subscribe() дозволяє іншим користувачам отримувати всі записки. Метод subscribe() викливається кожного разу, коли будь-хто публікує нову записку.

У вашому додатку React давайте викличемо subscribe() усередині componentWillMount(), що викликається одразу ж до того, як відбудеться початковий рендеринг у життєвому циклі застосунку.

1
componentWillMount() {
2
  pubnub.subscribe({
3
    channel: channel,
4
    restore: true,
5
    connect: () => this.connect(),
6
    message: (m) => this.success(m)
7
  });
8
}

Метод subscribe працює асинхронно, і коли кожну  операцію вдало закінчено, відбувається виклик функції зворотного виклику message. У ній давайте оновимо список записів, задавши стан масиву stickieList, що було визначено в конструкторі на початку.

В React при зміні ваших даних за допомогою setState автоматично відбувається оновлення представлення.

1
success(m) { 
2
  let newList = [m].concat(this.state.stickieList);
3
  this.setState({stickieList: newList});
4
}

Ми створимо представлення (компонент UI ) пізніше.

У функціях зворотного виклику ви, ймовірно, помітили синтаксис зі стрілками, що виглядає доволі смішно, – =>. Це стрілочні функції, синтаксис яких коротше, ніж вираз для функцій ES5. Також цей вираз лексично пов'язує значення this. Знов-таки, за допомогою Babel ми можемо використовувати всі можливості ES6!

Також ми використовуємо необов'язкову функцію зворотного виклику connect для методу subscribe для отримання “history” (* історії). Завдяки їй ми отримаємо попередні дані, коли з'єднання з PubNub встановлюється в перший раз.

1
connect() { 
2
  pubnub.history({
3
    channel: channel,
4
    count: 50,
5
    callback: (m) => {
6
      m[0].reverse();
7
      for (var v of m[0]) {
8
        let newList = this.state.stickieList.concat(v);
9
        this.setState({stickieList: newList});
10
      }
11
    }
12
  });
13
}

history() – це частина можливості  Storage and Playback, яку надає PubNub (* сховище и відтворення), і в нашому випадку відбувається отримання останніх 50 повідомлень із PubNub. В функції зворотного виклику success оновіть представлення, задавши стан масиву stickieList тут також.

Публікація повідомлень

Давайте створимо клас StickieWritable. Це – компонент записок-наклейок, до якого вводяться користувацькі дані.

Його рендерінг відбувається наступним чином:

1
render() {
2
  return (
3
    <div className={'stickie-note writable ' + this.props.color}>
4
      <textarea type='text' placeholder='Your new note...' onKeyUp={this.handleTextChange.bind(this)} />

5
    </div>  

6
  );
7
}

У текстовому полі прослуховуємо подію onKeyUp і кожного разу при його виникненні викливаємо функцію handleTextChange для перевірки, чи була нажата клавіша return/enter (* клавіша повернення каретки/ клавіша вводу). Зверніть увагу, що я прив'язую this при виклику функції. На відміну від React.createClass(), що є методом React стандарту ES5 для створення класу, клас ES6 не додає автоматично методи до зразка об'єкта, так що вам необхідно прив'язувати їх самостійно. (Існує декілька різних способів реалізувати теж саме)

В функції handleTextChange опублікуйте текст ті дані користувача в PubNub:

1
var data = {
2
  username: this.props.username,
3
  color: this.props.color,
4
  text: e.target.value,
5
  timestamp: Date.now()
6
};
7
8
pubnub.publish({
9
  channel: channel, 
10
  message: data, 
11
  callback: e.target.value = '' // resetting the text field

12
});

Тепер при набиранні користувачем якого-небудь тексту на стикері та натисканні return повідомлення буде надіслано до PubNub, і всі інші користувачі отримають повідомлення одночасно (протягом ¼ секунди!).

Створення компонентів UI

UI додатка складається з декількох компонентів UI, що виглядають наступним чином:

PubNub Stickie Components in React AppPubNub Stickie Components in React AppPubNub Stickie Components in React App

1. CollabStickies (* стикери для сумісного використання)
2. StickieWritable (* стикер для створення нової нотатки)
3. Stickie (* стикер)
4.StickieList (* список стикерів)

З компонентами 1 і 2 ми вже ознайомилися, так що давайте створимо 3-й компонент – індивідуальний стикер.

Створіть новий файл stickie.jsx для рендерінгу UI за допомогою JSX. На відміну від компонента StickieWritable, це – компонент UI тільки для зчитування без функціональності UX (* досвід взаємодії). У нього є тільки функція render() для прорисовування стикера разом із текстом, використовуючи дані prop.

Власне, при кожному отриманні користувачем повідомлення від іншого користувача повідомлення відображується на новому стикері.

1
import React from 'react';
2
import ReactDOM from 'react-dom';
3
4
export default class Stickie extends React.Component {
5
  render() {
6
    return (
7
      <div className={'stickie-note ' + this.props.color} >
8
        <p className='note'>{this.props.text}</p>

9
        <p className='username'>{this.props.username}</p>

10
      </div>  

11
    );
12
  }
13
}

Далі ми будемо створювати інший компонент UI – stickieList.jsx, що є контейнером для 3-го компонента та містить групу стикерів.

Анімування компонентів

Імпортуйте Stickie.jsx і всі залежності до StickieList.jsx. Тут я використовую додаток ReactCSSTransitionGroup та користувальницький шрифт для веб.

1
import React from 'react';
2
import ReactDOM from 'react-dom';
3
import ReactCSSTransitionGroup from 'react/lib/ReactCSSTransitionGroup';
4
import Stickie from './stickie';
5
import webfontloader from 'webfontloader'

Ви можете встановити завантажник шрифту для Веб за допомогою npm:
$ npm install webfontloader

Потім ви можете завантажити будь-який користувальницький шрифт на свій вибір. Ви можете поглянути на початковий код, щоб подивитися, як імпортується користувальницький шрифт Google.

В render() використовуємо стрілкову функцію ES6 та map() для ітерації по масиву та використовуємо stickieList для рендерингу кожного компонента Stickie, що тільки-но створили:

1
export default class StickieList extends React.Component {
2
  render() {
3
    let items = (this.props.stickieList || []).map((item) => 
4
      <li key={item.username + '-' + item.timestamp} >
5
        <div className="stickieWrapper">
6
          <Stickie text={item.text} color={item.color} username={item.username}/>

7
        </div>

8
      </li>);

9
10
    return (
11
      <ReactCSSTransitionGroup transitionName='animation' transitionEnterTimeout={500} transitionLeaveTimeout={500} component='ul' id="stickiesList">
12
        {items}
13
      </ReactCSSTransitionGroup>  

14
    )
15
  }
16
}

Створити анімацію певних компонентів можна за допомогою <ReactCSSTransitionGroup>. Встановлюємо transitionName, що вам необхідно використовувати у вашому CSS для визначення стилю анімування. Також зверніть увагу на атрибут key в <li>. Вам необхідно використовувати унікальний ключ для анімування кожного компонента, коли ви використовуєте <ReactCSSTransitionGroup>.

React додає додаткові імена класів. Наприклад, коли transitionName має значення ‘animation’, то у вас також будуть  ‘animation-enter’, ‘animation-enter-active’, ‘animation-leave’ та  ‘animation-leave-active’.

Нижче наведено код для /css/style.css:

1
.animation-enter {
2
  opacity: 0.1;
3
  transform: scale(1.3);
4
  transition: all 1s ease-out;
5
 }
6
.animation-enter.animation-enter-active {
7
  opacity: 1;
8
  transform: scale(1);
9
 }
10
...

От ви і створили веб-додаток для сумісного використання, що працює в режимі реального часу, за допомогою React.js та PubNub! Сподіваюся, що вам сподобався посібник!

PubNub Stickie app gif animationPubNub Stickie app gif animationPubNub Stickie app gif animation

Ви можете ознайомитися з повним кодом, включаючи CSS, у цьому репозиторії GitHub. Хоча я використовувала у цьому посібнику «легку» версію – app-lite.jsx, ви можете поглянути на app.jsx, де показано більше можливостей.

Якщо ви зацікавлені у створенні більшої кількості додатків, що працюють в режимі реального часу, наприклад, додатки для чату, багатокористувацьких ігор, комерційних застосунків тощо, то відвідайте PubNub та ознайомтеся там з безліччю ресурсів!

Хочете познайомитися з React краще?

Ми маємо курс, присвячений спеціально розвитку ваших умінь роботи з React наскільки це можливо. У цьому курсі ви ознайомитесь із основами створення сучасних веб-додтків за допомогою React і Redux. Ви будете використовувати ці дві бібліотеки для створення повноцінного веб-додатка.

Ви почнете з простішої архітектури та поступово створите веб-додаток, додаючи можливість за можливістю. Ви вивчите базові концепції, такі як tooling, reducers и routing. Також ви вивчите деякі більш складні техніки: smart и dumb components, pure components та asynchronous actions. Наприкінці ви створите повноцінний додаток, де будуть карточки з текстом та малюнками для вивчення за допомогою повторення з інтервалами.

Цікаво? Зацініть!

Посилання

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.