Що таке шорт і лонг та як їх використовувати у торгівлі криптовалютами?

Що таке шорт і лонг

Головне

  • Шорти та лонги – короткі та довгі позиції (на продаж та на покупку) у трейдингу . Застосовуються головним чином під час маржинальної торгівлі, тобто торгівлі з плечем.
  • Більшість криптовалютних активів характерна висока волатильність. Використання шортів та лонгів дає можливість трейдерам отримувати прибуток у процесі цінових коливань.
  • При торгівлі в довгих і коротких позицій слід пам’ятати про хеджування — певні дії, спрямовані на захист від ситуацій, коли ринок рухається у протилежному напрямку відкритим позиціям.

Походження шортів та лонгів

У середньовічній Європі для обліку боргів використовувалися ціпки-бирки або лічильні палиці, що виготовляються з ліщини. На одній із граней бірки поперечними насічками позначали суму, що пускається в оборот, після чого розбирали бірку вздовж через насічки, але не повністю, а з відрубом в районі «рукоятки». В результаті виходила довга частина з рукояткою (stock) та коротка частина (foil), що доповнює цю довгу частину до повної палички. Насічки були на обох частинах. За збігом цих частин проводився контроль. Вважалося, що через фактуру ліщини підробка була неможлива. Дві частини зберігали дві сторони-учасниці транзакції. Із цієї практики, ймовірно, виникли терміни «фондовий ринок» (stock market), а також «лонг» (long) і «шорт» (short).

Висловлювання «короткі» і «довгі» позиції набули поширення на американських фондових і товарно-сировинних біржах 1850-ті роки. Можливо, найраніша згадка про короткі і довгі позиції присутня в журналі The Merchant’s Magazine, and Commercial Review, Vol. XXVI, за січень-червень 1852 року.

Незважаючи на назви, період для короткої позиції може бути досить довгим (тиждень, місяць), а період для лонга досить коротким. Зі світу традиційних фінансів терміни шорт і лонг перекочували в біткоін-індустрію.

Хто такі «бики» та «ведмеді»

Біржових гравців прийнято називати биками чи ведмедями залежно від того, якої стратегії вони йдуть. Тих, хто грає на підвищення (тобто тих, хто відкриває лонги), називають «биками», а гравців, які розміщують короткі позиції, тобто ставлять на зниження ринку — «ведмедями».

Ці терміни умовні: на крипторинці немає чистих бугаїв і ведмедів, часто один і той же трейдер одночасно торгує і в шорт, і в лонг, хоча обсяги позицій можуть відрізнятися.

Що таке лонг

Лонг (довга позиція) – купівля активу в очікуванні того, що він зросте в ціні. Розмір прибутку залежить від збільшення вартості активу. Довга позиція є найбільш популярним типом угоди у роздрібних інвесторів та використовуються на спотовому ринку.

Що таке шорт

Шорт простими словами – продаж фінансового інструменту в очікуванні, що він подешевшає.

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

Приклад

У грудні 2017 року трейдер придбав біткоїни по $19 000 за монету. Він продав ці монети в той же період за $19 000, а потім виплатив позикодавцю приблизно $6000 за кожен BTC, коли в лютому 2018 року ціна значно знизилася . З кожної монети він отримав прибуток у $13 000.

До чого тут маржинальна торгівля

Якщо на спотовому ринку криптовалют можна, по суті, торгувати лише довгими позиціями (хоча і є прийоми, за логікою схожі на шортинг), то в маржинальній торгівлі стає можливим повноцінне відкриття коротких.

У рамках маржинальної торгівлі, яка дає можливість здійснювати угоди з плечем, користувач повинен надати заставу — внести на депозит суму (маржу), яка гарантує виплату боргових зобов’язань за встановленими біржею правилами.

Концепція маржі тісно пов’язана з концепцією левериджу або кредитного плеча (leverage) – множника, який збільшує доступний для операції депозит користувача за рахунок позикових коштів. На ринку криптовалют цей коефіцієнт може коливатися від 2:1 до 100:1 та більше. Тобто торгівля із плечем 50x означає, що при внесенні на депозит готівки на суму $100 ви можете відкрити позиції на суму до $5000.

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

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

У класичній торгівлі із плечем на фондовому ринку ліквідації позиції передує так званий маржин-кол — вимога додаткового забезпечення. Часто маржин-коллом називають безпосередньо момент ліквідації, на сленгу криптотрейдерів – “зловити моржа”.

Невдалу угоду трейдер може завершити самостійно, не чекаючи на ліквідацію. При цьому він втрачає не всю позицію, а лише частину маржі. Самостійно ліквідувати позицію можна вручну і за допомогою “стоп-лосса” (Stop Loss) – ордера для обмеження торгових ризиків, що передбачає автоматичне закриття угоди при досягненні певної цінової позначки.

Що таке хеджування?

На криптовалютному ринку застосовується механізм, відомий як хеджування — страхування на випадок, якщо тренд руху ціни активу не відповідає позиції трейдера. Наприклад, у вас відкрита довга позиція, а ціна криптовалюти знижується.

В основі хеджування – відкриття шорт-позицій, які врівноважують лонг-позиції та дозволяють залишитися «в нулі» при небажаній зміні ринкової ситуації. Інвестор залишає початкову лонг-позицію незайманою і відкриває шорт або ж використовує додаткові можливості.

Хеджування позиції — рішення для середньо- та довгострокової стратегії. Цей механізм дещо суперечить внутрішньоденному трейдингу, де переважають ринкові спекуляції. Популярний спосіб хеджування позицій передбачає використання ф’ючерсних контрактів: безстрокових та термінових.

Безстрокові контракти працюють за таким принципом: щовісім годин встановлюється так звана ставка фінансування. Останню учасники угод платять один одному замість того, щоб переказувати самі контракти або їх повні вартості. Залежно від ринкової ситуації платять ставку або власники лонг-контрактів власникам шортів, або навпаки.

Термінові контракти виконуються автоматично, якщо інвестор не закриває їх до дня експірації. Хеджуватися можна не лише ф’ючерсами, а й опціонами — похідними фінансовими інструментами для більш розвинених учасників ринку.

Що таке усереднення?

У рамках цієї стратегії інвестор скуповує актив за дедалі нижчою ціною, знижуючи тим самим середню вартість покупки.

Приклад

Ціна біткоїну досягла $29000, потім почала знижуватися. Побачивши фазу корекції, трейдер став купувати монети на послідовних рівнях зниження: $28000, $26000, $24000, $22000, $20000. Середня ціна покупки склала $24000. Після фази корекції курс почав зростати і згодом повернувся до рівня $29000 доларів.

Плюси та мінуси лонгів та шортів

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

Шортинг може бути ефективною інвестиційною стратегією, але набагато ризикованіший, ніж вкладення на тривалий термін або усереднення. Відкривати короткі позиції великі суми варто лише досвідченим трейдерам, здатним комплексно аналізувати ринкову динаміку.

Спробувати себе у криптотрейдінгу можна на криптобіржі Binance. На цей час це сама велика криптобіржа с великим вибором інструментів для торгівлі.

Всім профіту та будьте обережні при інвестуванні в крипту.

Крапка з комою в JavaScript: Чи дійсно вона вам потрібна?

JavaScript

У JavaScript крапки з комою є необов’язковими.

// Both statements work the same way
console.log("Hello")
console.log("Hello");

Однак є ситуації, в яких пропуск крапки з комою може призвести до небажаних наслідків. Тому немає однозначної відповіді на питання, чи слід використовувати крапку з комою, чи ні.

Використання крапок з комою завжди викликає суперечки у спільноті JavaScript. Існують вагомі аргументи на користь використання крапки з комою. Але також є вагомі причини, чому їх не слід застосовувати.

Це вичерпний посібник з використання крапок з комою в JavaScript.

Спочатку ми розглянемо правила використання крапок з комою у коді JavaScript. Потім ви дізнаєтеся, як працює автоматична вставка крапки з комою за кадром. І останнє, але не менш важливе: ви побачите список плюсів та мінусів використання крапок із комою.

Наприкінці цього посібника ви зможете вирішити, чи хочете ви використовувати крапки з комою чи ні.

Посібник з використання крапок з комою в JavaScript

Перш ніж обговорювати плюси та мінуси використання крапок із комою, необхідно зрозуміти, як вони взагалі використовуються.

Необхідне використання: Розділити два оператори в одному рядку

Якщо у вас є два оператори JavaScript в одному рядку, ви повинні поділити їх крапкою з комою. Можливо, найпоширенішим прикладом цього є цикл for.

Наприклад:

const numbers = [1, 2, 3, 4, 5];

for (let i = 0; i < numbers.length; i++) {
    console.log(numbers[i]);
}

На виході:

1
2
3
4
5

Цикл for не буде працювати без крапки з комою, якщо його умова задається в одному рядку.

Необов’язкове використання: Крапки з комою як роздільники операторів

Крім поділу операторів для одного рядка, JavaScript немає інших обов’язкових випадків використання крапки з комою. Однак, за бажанням, ви можете використовувати крапки з комою для завершення оператора, навіть якщо були розриви рядків.

Ось кілька поширених прикладів операторів, які можна завершити крапкою з комою:

let i;                        // variable declaration
i = 5;                        // value assignment
let x = 9;                    // declaration and assignment
var fun = function() {...};   // function definition
alert("hi");                  // function call

Пам’ятайте, що всі вищезгадані крапки з комою необов’язкові. Код працюватиме і без них.

Уникайте крапок із комою

Є ситуації, у яких слід уникати використання крапок із комою.

Уникайте крапок з комою після '}'. Не ставте крапку з комою після закриття фігурної дужки }.

Єдиним винятком є ​​оператор присвоєння, наприклад, такий:

var data = {name: "Alice", age: 25};

У цьому випадку можна використовувати крапку з комою.

Ось кілька прикладів того, як не використовувати крапку з комою після фігурної дужки, що закриває:

if  (...) {...} else {...}
for (...) {...}
while (...) {...}
function (arg) { /* actions */ }

Уникайте крапок з комою після ) в операторах if, for, while або switch.

У попередньому розділі ви дізналися, що не слід використовувати крапку з комою після закриття фігурної дужки. Однак якщо ви випадково це зробите, це буде просто проігноровано.

Жодної шкоди від цього не станеться. Але якщо ви поставите крапку з комою там, де її не повинно бути, то виникнуть проблеми.

Не додавайте крапку з комою після закриває дужки ) в:

  • операторів If
  • циклах For
  • циклах While
  • операторах Switch

Давайте розглянемо приклад того, чому важливо пам’ятати.

Якщо ви напишете оператор if наступним чином:

if (0 > 1); { console.log("Hello") }

Це еквівалентно наступному:

if (0 < 1);

console.log("Hello")

У цьому випадку він виводить повідомлення на консоль, хоча явно не повинен цього робити. Це тому, що крапка з комою повністю завершує оператор if. Потім блок коду, що йде за оператором if, виконується як окремий. Тому будьте обережні та не зловживайте крапкою з комою!

Винятки при використанні крапки з комою

Раніше у цій статті ви бачили приклад циклу for з крапкою з комою. Це винятковий випадок використання крапки з комою.

Погляньте на цей простий цикл:

for (let i = 0; i < 10 ; i++) { } // Works

Як ви можете бачити, крапка з комою не ставиться відразу після i++ .

Насправді після третього оператора в циклі for не можна ставити крапку з комою.

Якщо ви так зробите, то виникне синтаксична помилка:

for (let i = 0; i < 10 ; i++;) { } // SyntaxError

Це все, що вам потрібно знати, коли йдеться про правила використання крапок з комою в JavaScript.

Тепер давайте коротко обговоримо, чому використання крапок з комою в JavaScript необов’язкове.

Автоматична вставка крапки з комою у JavaScript

JavaScript не вимагає крапок з комою (за винятком одного виключення, яке ви бачили раніше).

Це відбувається тому, що JavaScript досить розумний і може автоматично додавати крапки з комою там, де потрібно.

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

Такий процес називається автоматичною вставкою крапок з комою ( Automatic Semicolon Insertion . ASI).

Правила ASI у JavaScript

Парсер JavaScript додає крапку з комою в будь-якому з наступних випадків:

  1. Наступний рядок коду починається з коду, який явно перериває поточний рядок коду.
  2. Коли наступний рядок коду починається з }.
  3. Досягши кінця файлу.
  4. Якщо будь-який з наступних операторів зустрічається у вигляді окремого рядка
  • return (повернення)
  • break (перервати)
  • throw (викинути [помилку])
  • continue (продовжити)

Важливо розуміти, що ASI не завжди є коректним на 100%.

Крапка з комою використовується для поділу операторів на JavaScript, а не для їх завершення.

Це те, що ASI намагається зробити вас.

Якщо говорити простіше, то правила ASI можна сформулювати так:

Не кожне перенесення рядка вимагає крапки з комою. Однак розрив рядка, який не піддається парсингу без крапки з комою, потребує її використання.

Наприклад:

let x
x
=
10
console.log(x)

Цей фрагмент коду інтерпретується ASI як:

let x;
x = 10;
console.log(x);

В даному випадку ASI проробив відмінну роботу, зумівши розібратися в тому, як триває код між рядками 2-4.

Однак, іноді він може не знати, чого ми намагаємося досягти.

Наприклад, цей рядок коду призводить до помилки

const s = 'World'
const ab = "Hello" + s

[3].forEach(n => console.log(n))

В результаті виникає така помилка:

Uncaught TypeError: s[3].forEach is not a function
    at :4:5

За описом помилки ви можете здогадатися, чому це відбувається.

Причина, через яку цей валідний фрагмент коду не працює, полягає в тому, що ASI не вставляє крапку з комою після другого рядка.

Натомість, він інтерпретує рядки 2 і 4 як продовження одного і того ж оператора наступним чином (відповідно до правила ASI номер 1):

const s = 'World';
const ab = "Hello" + s[3].forEach(n => console.log(n));

ASI думає, що s – це масив, і ви намагаєтеся отримати доступ до його 4 елемента за допомогою s [3] .

Але це не те, що ви плануєте здійснити.

Щоб змусити цей рядок працювати так, як очікується, необхідно вручну додати крапку з комою наприкінці другого рядка:

const s = 'World'
const ab = "Hello" + s;

[3].forEach(n => console.log(n)) // Prints '3'

Тепер код працює так, як передбачалося.

Інший приклад, коли ASI може викликати проблеми, – це оператори return.

Наприклад:

function getData() {
  return
  {
    name: 'Bob'
  }
}

console.log(getData())

На виході:

undefined

В результаті виводиться undefined, хоча малося на увазі, що з’явиться ім’я {name: 'Bob'}.

Так відбувається тому, що 4 правило ASI говорить, якщо оператор return зустрівся у вигляді окремого рядка, то ставиться крапка з комою.

Тому ASI бачить наведений вище код так:

function getData() {
  return;
  {
    name: 'Bob'
  }
}

console.log(getData())

Іншими словами, функція getData() нічого не повертає, а потім випадково створює об’єкт, з яким нічого не робить.

Таким чином, в консолі ви бачите undefined.

Для виправлення цього потрібно додати фігурну дужку, що відкриває, в той же рядок, що і оператор return:

function getData() {
  return {
    name: 'Bob'
  }
}

console.log(getData())

На виході:

{
  name: "Bob"
}

Тепер цей фрагмент коду працює як належить.

Завдяки цьому розділу ви навчилися бути обережними з ASI. Незважаючи на те, що в більшості випадків він діє правильно, іноді його інтерпретація ваших намірів може виявитися неправильною.

Далі перейдемо до найцікавішого, тобто до причин, з яких ви повинні або не повинні використовувати крапку з комою JavaScript.

Чому ви повинні використовувати крапку з комою: 5 причин

Використання або невикористання крапок із комою викликає спекотні суперечки серед веб-розробників.

Ось 5 причин, з яких ви повинні використовувати крапку з комою у своєму коді.

1. Іноді обов’язкова

Як було сказано раніше у цій статті, іноді необхідно використовувати крапку з комою.

Наприклад, якщо ви пишете цикл for, необхідно використовувати крапку з комою при вказівці параметра циклу та умов. В іншому випадку цикл не працюватиме.

Крім того, ASI (автоматична вставка крапки з комою) JavaScript не завжди відповідний на 100%.

Іноді він може неправильно витлумачити ваші наміри і не додати крапку з комою там, де вона потрібна. Це може призвести до появи непередбачених помилок у коді.

Один із таких прикладів ви також бачили раніше у цьому посібнику.

2. Ви звикли використовувати крапки з комою

Можливо, у процесі роботи ви звикли до використання крапок із комою в коді.

У деяких інших мовах широко використовуються крапки з комою, тому звикання до них є звичайною справою. Якщо ваш мозок не сприймає код JavaScript без крапок із комою, навіщо від них відмовлятися?

Не соромтеся використовувати крапки з комою, щоб зробити код більш зрозумілим для вас, якщо це те, що ви звикли робити.

3. Явно вказує на закінчення оператора

Крапка з комою – це простий спосіб чітко позначити закінчення оператора. При використанні крапки з комою немає місця для плутанини. Рядок коду закінчується на крапці з комою.

4. Менше приводів для занепокоєння

Якщо ви завжди використовуєте крапку з комою, то не варто переживати з приводу ASI. Це дає вам менше приводів для занепокоєння.

Після кожного рядка коду вам не потрібно замислюватися про те, чи зіпсує відсутність крапки з комою ситуацію чи ні. Однак ASI все одно може зіпсувати все, як ви бачили на прикладі оператора return .

5. ASI може бути змінено

Правила ASI можуть змінитися у майбутньому. Хоча це малоймовірно, але таке можливо. Таким чином, покладатися на правила ASI про вставку крапок з комою завжди за одним і тим же принципом надійно не на 100%.

Якщо ви пишете код з урахуванням поточного ASI, можете зіткнутися з деякими проблемами, якщо правила поміняються. Але майте на увазі, що у 99,9% випадків ASI виконує свою роботу коректно. Більше того, правила навряд чи зміняться найближчим часом.

Тепер, коли ви побачили безліч причин для використання крапок з комою, поговоримо про те, чому їх не слід використовувати.

Чому не слід використовувати крапки з комою: 3 причини

Зверніть увагу, що якщо ви чуєте, як хтось каже: “Ніколи не слід використовувати крапку з комою”, він помиляється. Це тому, що крапка з комою в окремих випадках обов’язкова.

У будь-якому випадку, поговоримо про мінуси крапок з комою, перерахувавши 3 причини, з яких їх не слід використовувати.

1. Крапки з комою вставляються автоматично

Як ви вже з’ясували, крапки з комою вставляються ASI. Таким чином, вам не потрібно писати те, що все одно буде проігноровано.

2. Менше написаного коду та менше шуму

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

3. Кілька операторів в одному рядку – погана практика

Використання крапок із комою дозволяє записувати по кілька операторів на одному рядку. Але це погана практика.

Ви ніколи не повинні писати оператори в одному рядку (якщо це не потрібно).

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

Так використовувати крапки з комою чи ні?

Під час вивчення цієї статті ми обговорили причини, через які варто і не слід використовувати крапку з комою.

Як показує практика, є набагато більше причин для використання капок з комою, ніж для її відсутності. Таким чином, я рекомендую використовувати крапки з комою. Проте рішення лишається за вами.

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

Також пам’ятайте, що потрібно бути послідовним у застосуванні крапок з комою та без них.

Якщо ви пропустили одну крапку з комою, то пропускайте їх усі (крім обов’язкових). Ви також можете налаштувати свій лінтер на автоматичне видалення крапок з комою.

Висновок

Сьогодні ви дізналися про використання крапок з комою у JavaScript. Нагадаємо, що крапки з комою не є обов’язковими у JavaScript. Водночас процес автоматичної вставки крапки з комою (ASI) додає крапки з комою там, де це необхідно.

Однак ASI не є правильним у 100% випадків. Крім того, у деяких ситуаціях ви просто зобов’язані використовувати крапку з комою. Інакше код не працюватиме.

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

Переклад статті “JavaScript Semicolon: Do You Really Need It? (Updated 2022)

React, Vue, Angular. Що краще?

React, Vue, Angular. Що краще?

Під час розвитку веб-розробки 3 JavaScript-фреймворку стали добре відомі всім front-end розробникам: React, Vue.js та Angular.

React вважається бібліотекою інтерфейсу користувача, Angular – повномасштабним front-end фреймворком, що надає власні інструменти для всіх пов’язаних з розробкою веб-додатків функцій, а Vue – прогресивним фреймворком, реалізованим як додаткова розмітка для HTML.

Всі три фреймворки можуть використовуватися практично взаємозамінно для створення компонентних frontend-додатків з розширеними можливостями інтерфейсу користувача. Однак остаточний вибір залежить від вимог проекту та переваг розробника.

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

Архітектура

1. React

Як видно з офіційного прикладу Hello World нижче, React не вимагає певної структури проекту, і ви можете почати використовувати його всього з декількох рядків коду.

ReactDOM.render(

  <h1>Hello, world!</h1>,

  document.getElementById('root')
);

React-елементи є найбільш базовими складовими React-додатків. Оскільки React DOM забезпечує їхнє ефективне оновлення при кожній зміні, вони є більш потужними, ніж стандартні елементи DOM.

Більші будівельні блоки, відомі як компоненти, визначають незалежні складові, що багаторазово використовуються, які використовуються у всьому додатку. Вони приймають вхідні дані, відомі як пропи, та створюють елементи, які згодом представлені користувачеві. Найбільш поширений варіант структурування проекту полягає у розбитті інтерфейсу на такі компоненти як імпорт в основний компонент App.js та його наступний рендер у React DOM.

React побудований на JavaScript, але також широко використовується JSX (JavaScript XML), розширення граматики, що дозволяє створювати елементи, що одночасно містять JavaScript і HTML. React JavaScript API та блоки, написані за допомогою JSX, сумісні, але здебільшого JSX більш зручний для використання та дозволяє уникнути написання довгого та, можливо, неінтуїтивного створення HTML елементів за допомогою JavaScript. Для порівняння нижче представлений той самий компонент написаний за допомогою JSX:

const Hello = (props) => {
    return
<div>Hello {props.toWhat}</div>
; } const root = ReactDOM.createRoot(document.getElementById('root')); 
root.render(<Hello toWhat="World" />);

та React JavaScript API:

const Hello = (props) => {
    return React.createElement('div', null, `Hello ${props.toWhat}`);
}

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render React.createElement(Hello, {toWhat: 'World'}, null));

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

2. Vue

Основна бібліотека Vue.js зосереджена лише на шарі View. Її називають прогресивним фреймворком, тому що ми можемо розширити її функціональність за допомогою офіційних та сторонніх бібліотек, таких як Vue Router або Vuex, щоб перетворити її на справжній фреймворк.

Хоча Vue не пов’язаний із патерном MVVM (Model-View-ViewModel), його дизайн був частково натхненний ним. У Vue ви працюватимете в основному на рівні ViewModel, щоб переконатися, що дані програми обробляються таким чином, щоб фреймворк міг відобразити актуальний вид і стан програми за мінімальну кількість ре-рендерів.

Синтаксис шаблонів Vue дозволяє створювати компоненти, поєднуючи звичний HTML зі спеціальними директивами та можливостями. Цей синтаксис шаблонів є кращим, хоча чистий JavaScript та JSX також підтримуються. Компоненти Vue невеликі, самодостатні і можуть бути повторно використані у всьому додатку. Унікальною деталлю Vue є так звані Однофайлові компоненти (SFC) з розширенням .vue, які складаються з трьох частин – template, script та style , значення яких інтуїтивно зрозуміле кожному розробнику.

Типовий формат .vue файлу наведений нижче:

<template> 
... 
</template>  


<script>
... 
</script>

 
<style>
...
</style>

Template – написаний на розширеній версії HTML, він є директивою для фреймворку у тому, як проводити остаточну розмітку компонента з урахуванням його внутрішнього стану. Дозволяє створювати розмітку щодо умов або динамічно за допомогою vue-директив (v-if, v-for та ін.).

Script – призначений для написання логіки компонента та контролю його стану. Vue як і React дозволяє опціонально використовувати JavaScript, і TypeScript.

Style – вміщує CSS (так підтримує написання стилів на CSS пре-процессорах). Написані стилі енкапсулируются в компоненті не впливають інші компоненти.

Багатьом концепт приміщення всього необхідного коду для функціонування компонента в одному файлі видасться досить зручним. SFC є рекомендованим способом організації коду в Vue.js проектах, особливо великих. Як і у випадку з React, рекомендовано використовувати основний компонент App.vue для рендерування вашої програми.

3. Angular

AngularJS, оригінальний фреймворк, є MVC (Model-View-Controller) фреймворком. Але в Angular 2 немає суворого зв’язку з MV*-патернами, оскільки він також ґрунтується на компонентах.

Проекти в Angular структуровані на Модулі, Компоненти та Сервіси. Кожна програма Angular має як мінімум один рутовий компонент і один рутовий модуль.

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

Кожен компонент в Angular містить шаблон, логіку з метаданими та опціонально стилі, розділені на окремі файли на відміну від Vue. Метадані для компонента вказують Angular, де знайти будівельні блоки, необхідні створення і уявлення виду компонента. Шаблони Angular написані на HTML, але також можуть включати синтаксис шаблонів Angular зі спеціальними директивами, як і у випадку з Vue.

Сервіси Angular використовуються компонентами для делегування завдань, таких як отримання даних або перевірка введення. Вони є окремою частиною програм Angular, на відміну від React та Vue, яким потрібно встановлювати додаткові бібліотеки для досягнення подібних цілей. Хоча Angular не змушує їх використання, настійно рекомендується структурувати додатки як набір окремих сервісів, які можна використовувати повторно.

Angular побудований на TypeScript, тому рекомендується використовувати його, хоча звичайний JavaScript також підтримується.

Екосистема

Ви можете заощадити багато часу при розробці програм, використовуючи Open Source ПЗ. Оскільки вони пройшли через численні вдосконалення і були використані в багатьох проектах, вони зазвичай перевершують кастомно розроблені компоненти. Дуже важливо враховувати доступність попередньо створених елементів, тем та інших інструментів, які можуть спростити створення вашої програми.

1. React

Глобальне керування станом часто використовується у зовнішніх програмах для зберігання таких даних, як інформація про користувача, токени і т.д. Redux – найпопулярніший проект управління глобальним станом JavaScript. Більшість React-розробників використовують офіційний React-біндинг для Redux, який підтримує команда проекту.

Оскільки React дуже популярний, за допомогою простого пошуку в Гуглі або на Гітхабі дуже легко знаходити готові компоненти та пекеджі практично на будь-який смак та необхідність.

Екосистема React також включає React Native, що дозволяє створювати нативні програми для iOS та Android написані на React. Таким чином, React може стати чудовим вибором для створення мобільних програм з використанням веб-технологій.

React є частиною стека MERN, до якого входять MongoDB, ExpressJS, React та NodeJS. Перевагою даного стеку є єдина мова програмування Javascript.

2. Vue

Хоча Redux може бути використаний з Vue, проте офіційного біндингу, як у випадку з React, немає. Але не варто переживати, оскільки існує Vuex – офіційний аналог Redux, створений спеціально для програм Vue і підтримується командою розробки Vue.js.

У перші дні існування Vue було складніше знайти готові до використання компоненти. Але з того часу, як спільнота зросла, з’явився широкий вибір компонентів та бібліотек, які можуть бути використані для прискорення розробки.

Для розробки мобільних програм існує перспективний проект під назвою Weex, розроблений компанією Alibaba. Однак Weex далеко не такий зрілий та потужний, як React Native. Більше того, оскільки проект розробляється та використовується більше в Китаї, складніше знайти документацію та вирішення проблем англійською мовою.

Vue часто використовується з Laravel завдяки їхній гарній інтеграції. Laravel пропонує повну JavaScript та CSS підтримку, що дозволяє використовувати Vue у Laravel проектах.

3. Angular

Для управління станами в Angular також є офіційний проект NgRx, натхненний Redux.

Як і у випадку з Vue і React, існує безліч готових до використання компонентів, які легко імпортуються в Angular проекти. Однак варто пам’ятати про наявність багатьох офіційних компонентів у бібліотеці Angular Material. Це офіційний проект від Google, який пропонує готові компоненти (кнопки, списки, діалогові вікна тощо) для програм Angular.

NativeScript є оптимальним варіантом для створення кросплатформових мобільних додатків у Angular. Він також може бути використаний з Vue, але підтримка Angular більш розвинена.

Angular є частиною відомого стека MEAN, що складається також із MongoDB, ExpressJS та NodeJS. Подібно до стеку MERN, він повністю покладається на JavaScript як для фронтенду, так і для бекенда.

Продуктивність

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

Однак варто пам’ятати, що слідувати кращим практикам розробки і стежити за якістю коду часто більш важливо, ніж вибір фреймворку для кращої продуктивності програми. Тим не менш, розглянемо деякі показники продуктивності.

1. Бенчмарк JS фреймворків

Проект JS Framework Benchmark є гарним способом переглянути порівняння продуктивності різних фреймворків, за допомогою виконання базових операцій над таблицею з 1000 рандомізованих записів.

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

Також React і Vue демонструють високі показники використання пам’яті та швидкості ініціалізації, проте Angular вимагає для цього більше часу. Базовий скрипт запускається за 150-200 мілісекунд, і Angular більш вимогливий до пам’яті найчастіше через те, що це повноцінний фреймворк із функціоналом, для якого React або Vue проекти зазвичай встановлюють сторонні бібліотеки за потребою.

2. Дослідження продуктивності Perf Track

Проект Perf Track від Google Chrome Labs() ставить за мету перевірити продуктивність вебсайтів, написаних на популярних фреймворках. Давайте подивимося на дані нижче:

React метрика React метрика

 

Vue метрика Vue метрика

 

angular метрика Angular метрика

 

Варто зауважити, що наведені дані були зібрані на момент 1 листопада 2020 року для мобільних пристроїв і на них впливає не тільки вибір фреймворку, але і безліч інших факторів. Для третього пункту, непередбаченого зсуву лейауту сторінки при навантаженні елементів, вибір фрейворку зовсім мало впливає. Однак, спробуємо зробити деякі висновки.

Перше промальовування контенту та найбільше промальовування контенту показує, що Vue та React краще справляються з провантаженням і рендерингом сторінки, ніж Angular, якому зазвичай потрібно більше часу, щоб підготувати програму. Затримкою першого введення (3 пункт) є тимчасовий проміжок між процесом користувача (клік на кнопку, введення даних) і реакцією сторінки нею і, на щастя, все 3 фреймворка показують винятково позитивні результати за цим параметром. Також варто зауважити, що понад 70% додатків на Vue завантажують менше 1MB JavaScript для своєї роботи, тоді як інші 2 фреймворки та Angular зокрема зазвичай займають набагато більше пам’яті. Однак, потрібно розуміти, що це може означати, що більшість маленьких проектів написані на Vue, тоді як Angular використовується для більш потужних проектів.

3. Додаткові прийоми покращення продуктивності

Основними двома техніками, що покращують роботу фронтенд додатків, є SSR (server-side rendering) та віртуалізація. Рендеринг за сервера насправді є здатність докладання скомпілювати HTML-файли з сервера на повністю провантажену сторінку для користувача, а віртуалізацією є навантаження компонентів у міру їх вимоги (наприклад у міру скролінгу сторінки).

React має за замовчуванням офіційний пекедж ReactDOMServer для рендерингу на стороні сервера, а для віртуалізації багато хто використовує сторонні бібліотеки React-Virtualized та React-Window

Vue також за замовчуванням має SSR пекедж Server-Renderer, проте з віртуалізацією потенційні розробники можуть мати проблеми, оскільки навіть найпопулярніша бібліотека Vue Virtual Scroll List має кілька багів і не настільки стабільна, як її аналоги для інших фреймворків.

Angular вкотре підтверджує своє звання повноцінного фреймворку, маючи офіційний Angular Universal для серверного рендерингу та вбудовані компоненти для віртуалізації.

Складність навчання та популярність

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

1. React

На перший погляд може здатися, що React – найпростіший у використанні фреймворк, що просто імпортуємо бібліотеку, і можна писати JavaScript з використанням React API. Однак на самому початку ми вже розглянули, наскільки незручно виглядає простий Hello world! Приклад, написаний на чистому JavaScript, тому кожен початківець React девелопер повинен змиритися з фактом, що альтернативи навчанню JSX немає, оскільки його використання є аксіомою у суспільстві для створення HTML-лейауту компонентам. Спочатку необхідність частково переходити на «мікс» з JavaScript та HTML може здатися дещо неінтуїтивною. З іншого боку, починаючи з версії 16.8 React вводить функціональні компоненти,

const exampleComponent = (props) => {

   ... // JavaScript 

   return(

    ... // JSX 

  );

};  export default exampleComponent;

Також варто зауважити, що версія 17.0 привнесла можливість часткового апгрейду програми, що дозволяє зберегти функціонал, що покладається на застарілі концепти, і робить React добрим вибором для довгострокової перспективи.

React є найчастіше завантажуваним фреймворком зі статистики npm, і це означає, що у користувачів не повинно бути проблем з пошуком рішень на можливі проблеми при девелопменті, так само як і активність спільноти дозволяє не тільки успішно шукати, але й ставити свої питання на популярних платформах типу StackOverflow.

2. Vue

Одним із концептів, з яким потрібно познайомитися початківцям Vue розробникам, є розширений HTML синтаксис із директивами. Більшість основних Vue директив інтуїтивно зрозумілі – v-if для рендерингу за умови, v-for для рендерингу в циклі, v-on для біндингу функціоналу до івент листенерів тощо. Наявність лейауту, функціоналу та стилів в одному .vue файлі з інтуїтивним синтаксисом також робить розробку кожного компонента максимально простим і без перескакування між файлами.

З релізом Vue 3 у 2020 році, творці фреймворку вирішили безліч проблем, які мала спільнота з використанням Vue для великих проектів, ввівши можливості для ширшого реюзу функціоналу між компонентами. Також було покращено підтримку таких проектів за допомогою рефакторингу вихідного коду Vue на TypeScript.

Так як Vue є «наймолодшим» фреймворком, розмір спільноти природно менший, ніж у React і Angular, і загальна популярність старої версії Vue 2 в основному серед китайських користувачів також створювала деякі проблеми в обміні знаннями та пошуку відповідей на запитання. Однак за тією самою статистикою npm – Vue є лідером у прирості завантажень за останній рік. Значні поліпшення Vue 3 дозволяють бути впевненими, що Vue скоро може обігнати за популярністю Angular.

3. Angular

Звання повноцінного фреймворку не дається легко, і Angular розробникам доводиться знайомитись з багатьма концептами. Angular очікує, що розробники дотримуватимуться певної структури в написанні коду і постійно використовуватимуть модулі з сервісами, крім компонентів. Як і у випадку з Vue необхідно вивчити додатковий HTML синтаксис, що складається з ng-* директив. І варто пам’ятати, що Angular працює найкраще з TypeScript і у разі вибору цього фреймворку потрібно обов’язково ознайомитися з TypeScript. Також складність вивчення підвищує широке використання RxJS – бібліотеки для реактивного програмування, яка дозволить зручно організувати роботу з подіями та асинхронним кодом і є потужнішою, але водночас складною альтернативою промісам.

Будучи старішим фреймворком, ніж React або Vue, і еволюціонувавши зі свого прототипу Angular.js, Angular може похвалитися величезним співтовариством, і він все ще є популярним вибором фреймворку для великих проектів. Однак у першої версії Angular була досить відома проблема – складність апгрейду проекту на новіші версії, яка згодом була виправлена ​​в Angular 2 і вище. Проте останнім часом безліч проектів вважають за краще використовувати React або Vue, особливо ті, що починають як старт-апи з невеликими командами.


Ми розглянули з вами низку основних аспектів, що розрізняють React, Vue та Angular. Насамкінець хочеться сказати, що всі 3 фреймворки знаходяться в активній розробці і регулярно отримують апдейти, тому в поточних реаліях можна без зайвого занепокоєння використовувати будь-який з них. Неможливо передбачити довгострокову релевантність будь-якого з фреймворків, але важливо помітити, що Angular вже не росте так само швидко, як колись, a Vue навпаки розвивається активніше за інших, переймаючи корисні концепти у React і Angular.

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

Переклад статті “React vs Vue vs Angular

Redux Toolkit як засіб ефективної розробки

Redux

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

  • складність і “багатослівність” рекомендованих патернів для написання та організації коду, що тягне за собою велику кількість бойлерплейту;
  • відсутність вбудованих засобів управління асинхронною поведінкою та побічними ефектами, що призводить до необхідності вибору відповідного інструменту з безлічі аддонів, написаних сторонніми розробниками.

Для усунення цих недоліків розробники Redux представили бібліотеку Redux Toolkit. Цей інструмент є набір практичних рішень та методів, призначених для спрощення розробки додатків з використанням Redux. Розробники цієї бібліотеки мали на меті спростити типові випадки використання Redux. Цей інструмент не є універсальним рішенням у кожному з можливих випадків використання Redux, але дозволяє спростити код, який потрібно написати розробнику.

У цій статті ми розповімо про основні інструменти, що входять до Redux Toolkit, а також, на прикладі фрагмента нашої внутрішньої програми, покажемо, як їх використовувати у коді, що вже є.

Коротко про бібліотеку

Коротка інформація про Redux Toolkit:

  • до релізу бібліотека називалася redux-starter-kit;
  • реліз відбувся наприкінці жовтня 2019 року;
  • Бібліотека офіційно підтримується розробниками Redux.

Згідно з заявою розробників Redux Toolkit виконує такі функції:

  • допомагає швидко розпочати використання Redux;
  • спрощує роботу з типовими завданнями та кодом Redux;
  • дозволяє використовувати найкращі практики Redux за замовчуванням;
  • пропонує рішення, які зменшують недовіру до бойлерплейтів.

Redux Toolkit надає набір як спеціально розроблених, так і додає ряд інструментів, що добре себе зарекомендували, які зазвичай використовуються спільно з Redux. Такий підхід дозволяє розробнику вирішити, як і які інструменти використовувати у своєму додатку. Під час цієї статті ми будемо відзначати які запозичення використовує дана бібліотека. Більш повну інформацію та залежності Redux Toolkit можна отримати з опису пакету @reduxjs/toolkit.

Найбільш значущими функціями, які надає бібліотека Redux Toolkit є:

  • configureStore – функція, призначена спростити процес створення та налаштування сховища;
  • createReducer — функція, що допомагає лаконічно та зрозуміло описати та створити ред’юсер;
  • createAction – повертає функцію творця дії для заданого рядка типу дії;
  • createSlice – поєднує в собі функціонал createAction і createReducer;
  • createSelector – функція з бібліотеки Reselect, переекспортована для простоти використання.

Також варто відзначити, що Redux Toolkit повністю інтегрований з TypeScript. Докладнішу інформацію про це можна отримати з розділу Usage With TypeScript офіційної документації.

Застосування

Розглянемо використання бібліотеки Redux Toolkit на прикладі фрагмента програми, що реально використовується React Redux.

Примітка. Далі у статті наводиться вихідний код як без використання Redux Toolkit, так і з використанням, що дозволить краще оцінити позитивні та негативні сторони використання цієї бібліотеки.

Завдання

В одному з наших внутрішніх додатків виникла потреба додавати, редагувати і відображати інформацію про релізи програмних продуктів, які ми випускаємо. Для кожної з цих дій були розроблені окремі функції API, результати виконання яких потрібно додавати в Redux store. Як засіб управління асинхронною поведінкою та побічними ефектами будемо використовувати Thunk.

Створення сховища

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

import {
  createStore, applyMiddleware, combineReducers, compose,
} from 'redux';
import thunk from 'redux-thunk';
import * as reducers from './reducers';

const ext = window.__REDUX_DEVTOOLS_EXTENSION__;
const devtoolMiddleware = 
  ext && process.env.NODE_ENV === 'development' ? ext() : f => f;

const store = createStore(
 combineReducers({
   ...reducers,
 }),
 compose(
   applyMiddleware(thunk),
   devtoolMiddleware
 )
);

Якщо уважно поглянути на наведений код, можна побачити досить довгу послідовність дій, яку необхідно зробити, щоб сховище було повністю налаштовано. Redux Toolkit містить інструмент, покликаний спростити цю процедуру, а саме: функцію configureStore.

Функція configureStore

Даний інструмент дозволяє автоматично комбінувати редьюсери, додати мідлвари Redux (за замовчуванням включає redux-thunk), а також використовувати розширення Redux DevTools. Як вхідні параметри функція configureStore приймає об’єкт з такими властивостями:

  • reducer — набір ред’юсерів користувача,
  • middleware – опціональний параметр, що задає масив мідлварів, призначених для підключення до сховища,
  • devTools — параметр логічного типу, що дозволяє увімкнути встановлене у браузер розширення Redux DevTools (значення за промовчанням — true),
  • preloadedState – опціональний параметр, що задає початковий стан сховища,
  • enhancers – опціональний параметр, що задає набір підсилювачів.

Для отримання найбільш популярного списку мідлвар можна скористатися спеціальною функцією getDefaultMiddleware, що також входить до складу Redux Toolkit. Ця функція повертає масив із включеними за замовчуванням до бібліотеки Redux Toolkit мідлварами. Перелік цих мідлвар відрізняється залежно від того, в якому режимі виконується ваш код. У режимі production масив складається тільки з одного елемента – thunk. У режимі development на момент написання статті список поповнюється такими мідлварами:

  • serializableStateInvariant — інструмент, спеціально розроблений для використання в Redux Toolkit і призначений для перевірки дерева станів на наявність несеріалізованих значень, таких як функції, Promise, Symbol та інші значення, що не є простими JS-даними;
  • immutableStateInvariant – мідлвар з пакету redux-immutable-state-invariant , призначений для виявлення мутацій даних, що містяться в сховищі.

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

Тепер перепишемо ділянку коду, відповідальний створення сховища, скориставшись описаними вище інструментами. В результаті отримаємо наступне:

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import * as reducers from './reducers';

const middleware = getDefaultMiddleware({
  immutableCheck: false,
  serializableCheck: false,
  thunk: true,
});

export const store = configureStore({
 reducer: { ...reducers },
 middleware,
 devTools: process.env.NODE_ENV !== 'production',
});

На прикладі даної ділянки коду добре видно, що функція configureStore вирішує такі проблеми:

  • необхідність комбінувати ред’юсери, автоматично викликаючи combineReducers,
  • необхідність комбінувати мідлвари, автоматично викликаючи applyMiddleware.

А також дозволяє зручніше включити розширення Redux DevTools, використовуючи функцію composeWithDevTools з пакету redux-devtools-extension. Все сказане вище свідчить про те, що використання цієї функції дозволяє зробити код більш компактним і зрозумілим.

На цьому створення та налаштування сховища завершено. Передаємо його у провайдер і переходимо далі.

Дії, творці дій та редьюсер

Тепер розглянемо можливості Redux Toolkit щодо розробки дій, творців дій і редьюсера. Початковий код без використання Redux Toolkit був організований у вигляді файлів actions.js і reducers.js. Вміст файлу actions.js виглядав так:

import * as productReleasesService from '../../services/productReleases';

export const PRODUCT_RELEASES_FETCHING = 'PRODUCT_RELEASES_FETCHING';
export const PRODUCT_RELEASES_FETCHED = 'PRODUCT_RELEASES_FETCHED';
export const PRODUCT_RELEASES_FETCHING_ERROR =
  'PRODUCT_RELEASES_FETCHING_ERROR';

…

export const PRODUCT_RELEASE_UPDATING = 'PRODUCT_RELEASE_UPDATING';
export const PRODUCT_RELEASE_UPDATED = 'PRODUCT_RELEASE_UPDATED';
export const PRODUCT_RELEASE_CREATING_UPDATING_ERROR =
  'PRODUCT_RELEASE_CREATING_UPDATING_ERROR';

function productReleasesFetching() {
  return {
    type: PRODUCT_RELEASES_FETCHING
  };
}

function productReleasesFetched(productReleases) {
  return {
    type: PRODUCT_RELEASES_FETCHED,
    productReleases
  };
}

function productReleasesFetchingError(error) {
  return {
    type: PRODUCT_RELEASES_FETCHING_ERROR,
    error
  }
}

…

export function fetchProductReleases() {
  return dispatch => {
    dispatch(productReleasesFetching());
    return productReleasesService.getProductReleases().then(
      productReleases => dispatch(productReleasesFetched(productReleases))
    ).catch(error => {
      error.clientMessage = "Can't get product releases";
      dispatch(productReleasesFetchingError(error))
    });
  }
}

…

export function updateProductRelease(
  id, productName, productVersion, releaseDate
) {
  return dispatch => {
    dispatch(productReleaseUpdating());
    return productReleasesService.updateProductRelease(
      id, productName, productVersion, releaseDate
    ).then(
      productRelease => dispatch(productReleaseUpdated(productRelease))
    ).catch(error => {
      error.clientMessage = "Can't update product releases";
      dispatch(productReleaseCreatingUpdatingError(error))
    });
  }
}

Вміст файлу reducers.js до використання Redux Toolkit:

const initialState = {
 productReleases: [],
 loadedProductRelease: null,
 fetchingState: 'none',
 creatingState: 'none',
 updatingState: 'none',
 error: null,
};

export default function reducer(state = initialState, action = {}) {
 switch (action.type) {
   case productReleases.PRODUCT_RELEASES_FETCHING:
     return {
       ...state,
       fetchingState: 'requesting',
       error: null,
     };
   case productReleases.PRODUCT_RELEASES_FETCHED:
     return {
       ...state,
       productReleases: action.productReleases,
       fetchingState: 'success',
     };
   case productReleases.PRODUCT_RELEASES_FETCHING_ERROR:
     return {
       ...state,
       fetchingState: 'failed',
       error: action.error
     };

…

   case productReleases.PRODUCT_RELEASE_UPDATING:
     return {
       ...state,
       updatingState: 'requesting',
       error: null,
     };
   case productReleases.PRODUCT_RELEASE_UPDATED:
     return {
       ...state,
       updatingState: 'success',
       productReleases: state.productReleases.map(productRelease => {
         if (productRelease.id === action.productRelease.id)
           return action.productRelease;
         return productRelease;
       })
     };
   case productReleases.PRODUCT_RELEASE_UPDATING_ERROR:
     return {
       ...state,
       updatingState: 'failed',
       error: action.error
     };
   default:
     return state;
 }
}

Як ми можемо бачити, саме тут міститься більшість бойлерплейта: константи типів дій, творці дій, знову константи, але вже у коді редьюсера на написання всього цього коду доводиться витрачати час. Частково цього бойлерплейту можна позбутися, якщо скористатися функціями createAction і createReducer, які також входять до складу Redux Toolkit.

Функція createAction

У наведеній ділянці коду використовується стандартний спосіб визначення дії Redux: спочатку окремо оголошується константа, що визначає тип дії, після чого – функція творця дії цього типу. Функція createAction об’єднує ці об’яви в одне. На вхід вона приймає тип дії та повертає творця дії для цього типу. Автор дії може бути викликаний або без аргументів, або з деяким аргументом (корисне навантаження), значення якого буде поміщено в полі payload, створеного дії. Крім того, автор дії перевизначає функцію toString(), так що тип дії стає його рядковим уявленням.

У деяких випадках може знадобитися написати додаткову логіку для налаштування значення корисного навантаження, наприклад, прийняти кілька параметрів для творця дії, створити випадковий ідентифікатор або отримати поточну мітку. Для цього createAction приймає необов’язковий другий аргумент – функцію, яка використовуватиметься для оновлення значення корисного навантаження. Докладніше про цей параметр можна ознайомитись в офіційній документації.
Використовуючи функцію createAction, отримаємо наступний код:

export const productReleasesFetching =
  createAction('PRODUCT_RELEASES_FETCHING');
export const productReleasesFetched =
  createAction('PRODUCT_RELEASES_FETCHED');
export const productReleasesFetchingError =
  createAction('PRODUCT_RELEASES_FETCHING_ERROR');

…

export function fetchProductReleases() {
  return dispatch => {
    dispatch(productReleasesFetching());
    return productReleasesService.getProductReleases().then(
      productReleases => dispatch(productReleasesFetched({ productReleases }))
    ).catch(error => {
      error.clientMessage = "Can't get product releases";
      dispatch(productReleasesFetchingError({ error }))
    });
  }
}
...

Функція createReducer

Тепер розглянемо ред’юсер. Як і наш приклад, редьюсери часто реалізуються з допомогою оператора switch, з одним регістром кожному за обробленого типу дії. Цей підхід працює добре, але не позбавлений бойлерплейта і схильний до помилок. Наприклад, легко забути описати випадок default або встановити початковий стан. Функція createReducer спрощує створення функцій редьюсера, визначаючи їх як таблиці пошуку функцій обробки кожного типу дії. Вона також дозволяє суттєво спростити логіку іммутабельного поновлення, написавши код у “мутабельному” стилі всередині ред’юсерів.

“Мутабельний” стиль обробки подій доступний завдяки використанню бібліотеки Immer. Функція обробник може або “мутувати” переданий state для зміни властивостей, або повертати новий state, як при роботі в іммутабельному стилі, але завдяки Immer реальна мутація об’єкта не здійснюється. Перший варіант набагато простіше для роботи та сприйняття, особливо при зміні об’єкта з глибокою вкладеністю.

Будьте уважні: повернення нового об’єкта із функції перекриває “мутабельні” зміни. Одночасне застосування обох методів поновлення стану не спрацює.

Як вхідні параметри функція createReducer приймає такі аргументи:

  • початковий стан сховища,
  • об’єкт, що встановлює відповідність між типами дій та редьюсерами, кожен із яких обробляє якийсь певний тип.

Скориставшись методом createReducer, отримаємо наступний код:

const initialState = {
 productReleases: [],
 loadedProductRelease: null,
 fetchingState: 'none',
 creatingState: 'none',
 loadingState: 'none',
 error: null,
};

const counterReducer = createReducer(initialState, {
 [productReleasesFetching]: (state, action) => {
   state.fetchingState = 'requesting'
 },
 [productReleasesFetched.type]: (state, action) => {
   state.productReleases = action.payload.productReleases;
   state.fetchingState = 'success';
 },
 [productReleasesFetchingError]: (state, action) => {
   state.fetchingState = 'failed';
   state.error = action.payload.error;
 },

…

 [productReleaseUpdating]: (state) => {
   state.updatingState = 'requesting'
 },
 [productReleaseUpdated]: (state, action) => {
   state.updatingState = 'success';
   state.productReleases = state.productReleases.map(productRelease => {
     if (productRelease.id === action.payload.productRelease.id)
       return action.payload.productRelease;
     return productRelease;
   });
 },
 [productReleaseUpdatingError]: (state, action) => {
   state.updating = 'failed';
   state.error = action.payload.error;
 },
});

Як бачимо, використання функцій createAction і createReducer істотно вирішує проблему написання зайвого коду, але проблема попереднього створення констант все одно залишається. Тому розглянемо більш потужний варіант, що поєднує в собі генерацію і творців дій та редьюсера – функція createSlice.

Функція createSlice

Як вхідні параметри функція createSlice приймає об’єкт із наступними полями:

  • name – простір імен створюваних дій ( ${name}/${action.type});
  • initialState – початковий стан ред’юсера;
  • reducers – об’єкт з обробниками. Кожен обробник приймає функцію з аргументами state і action, action містить у собі дані у властивості payload та ім’я події у властивості name. Крім того, є можливість попередньої зміни даних, отриманих з події, перед їх потраплянням до редьюсера (наприклад, додати id до елементів колекції). Для цього замість функції необхідно передати об’єкт з полями reducer та prepare, де reducer – це функція-обробник дії, а prepare – функція-обробник корисного навантаження, що повертає оновлений payload;
  • extraReducers – об’єкт, що містить редьюсери іншого зрізу. Цей параметр може знадобитися в разі потреби оновлення об’єкта, що стосується іншого зрізу. Докладніше про цю можливість можна дізнатися з відповідного розділу офіційної документації.

Результатом роботи функції є об’єкт, званий “зріз (slice)”, з наступними полями:

  • name – ім’я зрізу,
  • reducer – ред’юсер,
  • actions – набір дій.

Використовуючи цю функцію для вирішення нашого завдання, отримаємо наступний вихідний код:

const initialState = {
 productReleases: [],
 loadedProductRelease: null,
 fetchingState: 'none',
 creatingState: 'none',
 loadingState: 'none',
 error: null,
};

const productReleases = createSlice({
 name: 'productReleases',
 initialState,
 reducers: {
   productReleasesFetching: (state) => {
     state.fetchingState = 'requesting';
   },
   productReleasesFetched: (state, action) => {
     state.productReleases = action.payload.productReleases;
     state.fetchingState = 'success';
   },
   productReleasesFetchingError: (state, action) => {
     state.fetchingState = 'failed';
     state.error = action.payload.error;
   },

…

   productReleaseUpdating: (state) => {
     state.updatingState = 'requesting'
   },
   productReleaseUpdated: (state, action) => {
     state.updatingState = 'success';
     state.productReleases = state.productReleases.map(productRelease => {
       if (productRelease.id === action.payload.productRelease.id)
         return action.payload.productRelease;
       return productRelease;
     });
   },
   productReleaseUpdatingError: (state, action) => {
     state.updating = 'failed';
     state.error = action.payload.error;
   },
 },
});

Тепер витягнемо із створеного зрізу творці дій та ред’юсер.

const { actions, reducer } = productReleases;

export const {
  productReleasesFetched, productReleasesFetching,
  productReleasesFetchingError,
…
  productReleaseUpdated,
  productReleaseUpdating, productReleaseUpdatingError
} = actions;

export default reducer;

Вихідний код творців дій, що містять виклики API, не змінився, за винятком способу передачі параметрів під час надсилання дій:

export const fetchProductReleases = () => (dispatch) => {
 dispatch(productReleasesFetching());
 return productReleasesService
   .getProductReleases()
   .then((productReleases) => dispatch(productReleasesFetched({ productReleases })))
   .catch((error) => {
     error.clientMessage = "Can't get product releases";
     dispatch(productReleasesFetchingError({ error }));
   });
};

…

export const updateProductRelease = (id, productName, productVersion, releaseDate) => (dispatch) => {
 dispatch(productReleaseUpdating());
 return productReleasesService
   .updateProductRelease(id, productName, productVersion, releaseDate)
   .then((productRelease) => dispatch(productReleaseUpdated({ productRelease })))
   .catch((error) => {
     error.clientMessage = "Can't update product releases";
     dispatch(productReleaseUpdatingError({ error }));
   });

Наведений вище код показує, що функція createSlice дозволяє позбутися значної частини бойлерплейта при роботі з Redux, що дозволяє не тільки зробити код компактнішим, лаконічнішим і зрозумілішим, але й витрачати менше часу на його написання.

Підсумок

На завершення цієї статті, хотілося б сказати, що незважаючи на те, що бібліотека Redux Toolkit не вносить нічого нового в управління сховищем, вона надає ряд набагато зручніших засобів для написання коду, ніж були до цього. Дані засоби дозволяють не тільки зробити процес розробки більш зручним, зрозумілим і швидким, але і більш ефективним, за рахунок наявності в бібліотеці ряду інструментів, що добре зарекомендували себе раніше.

Переклад статті “Redux Toolkit как средство эффективной Redux-разработки

Картка Binance тепер підтримує XRP, SHIB і AVAX

Картка Binance

Binance додала XRPSHIB і AVAX до списку підтримуваних криптовалют на Binance Cards, починаючи з 07:00 (UTC) 05 серпня 2022 року.
  • На даний момент картка Binance доступна лише для користувачів Binance, які проживають в ЄЕЗ, і українських біженців, які проживають у країні ЄЕЗ (Binance Refugee Crypto Card )Ви можете зареєструватися на Binance Card тут .
  • Станом на 07:00 (UTC) 2022-08-05 на Binance Card є 14 підтримуваних криптовалют: ADA, AVAX, BNB, BTC, BUSD, DOT, ETH, LAZIO, PORTO, SANTOS, SHIB, SXP, USDT і XRP .
  • Щоб витратити нещодавно підтримані криптовалюти за допомогою Binance Card, перейдіть до Інформаційної панелі картки > Пріоритет платежу > Редагувати, щоб додати, видалити або ранжувати криптовалюти для витрат відповідно до власних уподобань.
  • Користувачі повинні мати принаймні шість криптовалют у списку пріоритетів платежів. Можна вибрати максимум 12 криптовалют.
  • З додаванням XRP, SHIB і AVAX до Binance Card поточні параметри пріоритету платежу для наявних користувачів картки Binance не зміняться.
  • Binance Card випускається ліцензованою організацією UAB «Finansinės paslaugos Contis» і розповсюджується Swipe. Використання вами Binance Card регулюється умовами, викладеними в Угоді власника картки.

React Storybook

За допомогою React Storybook ви можете розробляти та проектувати компоненти інтерфейсу користувача за межами вашої програми в ізольованому середовищі. Це змінить спосіб розробки компонентів інтерфейсу користувача.

React Storybook
Ось так виглядає React Storybook.

Перш ніж ми почнемо

Сьогодні серверні системи стали дуже простими завдяки фреймворкам, таким як Meteor, і хмарним службам, таким як Firebase. Такі речі, як GraphQL і Falcor виведе серверні системи на новий рівень.

Отже, ми витрачаємо багато часу на створення програм на стороні клієнта, а не на роботу над серверною частиною. React змінив спосіб створення користувацьких інтерфейсів, але нам все ще потрібно наполегливо працювати, щоб створювати чудові користувацькі інтерфейси. Для цього ми пишемо багато коду на стороні клієнта, а не на стороні сервера.

Просто порахуйте КІЛЬКІСТЬ РЯДКІВ , які ви написали для СТОРОНИ КЛІЄНТА, і ви зрозумієте, що я маю на увазі.

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

Це важко

Завдяки гарячому перезавантаженню ми можемо дуже швидко розробляти та ітерувати інтерфейс користувача. Зазвичай ми робимо це в нашому додатку.

Але побудувати компонент у програмі важко. Дозвольте мені показати вам проблему.

Уявіть, що ми створюємо компонент списку завдань. Отже, він має кілька станів, і нам потрібно змінити інтерфейс для них. Ось список штатів:

  • У списку немає елементів.
  • У списку є кілька елементів (він не порожній).
  • Деякі з цих пунктів завершено.
  • Усі пункти в списку виконано.

Навіть якщо ми знайдемо спосіб відтворити ці стани всередині програми, нам потрібно якось їх задокументувати. Інакше новий розробник або дизайнер не зможе працювати над цими компонентами інтерфейсу користувача.

Я можу перерахувати багато таких проблем, як це. Але, я сподіваюся, ви зрозуміли суть.

Зустрічайте React Storybook

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

Після налаштування ви можете запустити консоль React Storybook, ввівши:

npm run book story

Потім він запустить веб-сервер на порту 9001 і виглядає так:

React Storybook

Після цього нам потрібно помістити наші компоненти (з їхніми різними станами ) у наведену вище консоль. Ми робимо це, пишучи набір історій.

Одна STORY має повертати елемент REACT. Потім ви взаємодієте з ним із React Storybook.

У наступному коді ми пишемо кілька історій для різних станів нашого компонента списку завдань.
(Тут наш компонент списку завдань називається «MainSection»)

import React from 'react';
import MainSection from '../MainSection';
import { storiesOf, action } from '@storybook';

storiesOf('MainSection', module)
  .add('all active', () => {
    const todoItems = [
      { id: 'one', text: 'Item One', completed: false },
      { id: 'two', text: 'Item Two', completed: false },
    ];

    return getMainSection(todoItems);
  })
  .add('some completed', () => {
    const todoItems = [
      { id: 'one', text: 'Item One', completed: false },
      { id: 'two', text: 'Item Two', completed: true },
    ];

    return getMainSection(todoItems);
  })
  .add('all completed', () => {
    const todoItems = [
      { id: 'one', text: 'Item One', completed: true },
      { id: 'two', text: 'Item Two', completed: true },
    ];

    return getMainSection(todoItems);
  });

function getMainSection(todos) {
  const actions = {
    clearCompleted: action('clearCompleted'),
    completeAll: action('completeAll')
  };

  return (

); }

Тоді ти маєш змогу взаємодіяти з ними у React Storybook ось так:

Storybook

Отже, інші у вашій команді можуть надати вам відгуки про ці компоненти інтерфейсу користувача. Крім того, дизайнери у вашій команді хотіли б попрацювати над цими компонентами інтерфейсу користувача та зробити їх гарним.

Переклад статті “Introducing React Storybook

Binance Card для біженців із України

binance card

Binance запустила Binance Card для біженців із України, які були змушені переїхати до країн ЄЕЗ через війну з Росією 📣🇺🇦

Binance Card створена у партнерстві з Contis. Це дозволить переміщеним українцям здійснювати або отримувати криптоплатежі та здійснювати купівлю в роздрібних торгових точках в ЄЕЗ, які приймають оплату карткою.

🙏🏻 Binance Charity співпрацює з різними неурядовими організаціями, щоб надати грошову допомогу за допомогою Binance Card для біженців. До слова, створений Binance «Фонд екстреної допомоги Україні» уже зібрав більше $1 млн.

📩 Отримання та використання віртуальної та фізичної Binance Card безкоштовне. Щоб отримати картку, біженцям потрібно мати або зареєструвати акаунт на Binance, пройти повну верифікацію за українським документом та прив’язати до акаунта європейський номер телефона. Для отримання картки використовуйте вашу поточну адресу у країні ЄЕЗ.

➡️ Гайд із замовлення Binance Card

📹 Відеогайд

💳 Замовити Binance Card

Також слід зазначити, що біженці, які звернулися до місцевих некомерційних організацій та подали заявку на отримання криптовалютних карток Binance Refugee Card, отримають 75 BUSD (1 BUSD = $1) щомісно (225 BUSD протягом трьох місяців) як підтримку від біржі.

Figma plugin API людською мовою

Figma

Зіткнувся з написанням плагіна для Figma і дивуюся, навіщо так складно? Ну, взагалі-то, нічого особливо складного немає. Але цей TypeScript, це навіщо все? Встанови модулі, налаштуйте публікацію. Скільки я не думав, єдине пояснення, навіщо все це потрібне, це захист від дурня. Типу, кому треба – розбереться, а іншим і нема чого лізти, говнокод плодити.

Ну так ми розвіємо цей снобістський тренд і прорубаємо шлях в API Figma для всіх бажаючих.

Суть у тому, що якщо відкинути все зайве, то в сухому залишку нам знадобиться лише три файли:

Figma plugin API людською мовою

Точкою входу плагіна є файл manifest.json. Виглядати він має так:

{
 "name": "Simple Plugin",
 "api": "1.0.0",
 "main": "plugin.js",
 "ui": "index.html",
 "editorType": [
   "figma"
 ]
}

Поле name це ім’я плагіна, воно буде відображатися в меню і на корінці вікна плагіна.

У полі api ми вказуємо версію api, поки це 1.0.0.

Поле editorType містить масив із перерахуванням редакторів, для яких розробляється плагін. Ми вказуємо лише figma.

Два поля main і ui, що залишилися, містять шляхи до файлів самого плагіна. ui вказує на html з версткою та логікою вікна плагіна. main посилається на js з логікою взаємодії плагіна з Figma.

Почнемо їх вивчення з ui, а значить із файлу index.html:

<button>Click Me</button>
<script>
   document.querySelector('button').onclick = () => {
       alert('Hello world!!!')
   }
</script>

Я помістив у нього кнопку та скрипт, що обробляє клік по цій кнопці. Натиснувши кнопку, виводиться вікно з текстом “Hello World!!!”. Тут важливо зрозуміти, що скрипт повинен перебувати усередині html. Підвантажувати скрипт атрибутом src плагін не вміє.

Ну, і останній файл, який нам потрібен для роботи плагіна, це plugin.js.

figma.showUI (
   __html__,
   {width: 400, height: 400}
);

Він дуже простий, в ньому ми тільки даємо Figma команду, відкрити вікно з вмістом нашого html. Другим параметром метод showUI приймає об’єкт, у якому ми вказуємо необхідний розмір вікна.

Ось, власне, і все. Нам залишилося лише відкрити редактор Figma та перейти в меню Plugins -> Development -> Import plugin from manifest…

Figma plugin API людською мовою

Вибираємо наш manifest.json, після чого в тому ж меню знаходимо наш плагін.

Figma plugin API людською мовою

Наш плагін готовий.

З документацією API Figma можна познайомитись тут.

AIRDROP – або як заробити на нових токенах

AIRDROP у крипті це не те що AIRDROP на iOS 🙂 AIRDROP – це безкоштовна роздача нових токенів (ну або умовна безкоштовна). Нові токени роздають, коли хочуть отримати у свій новий проект користувачів. Як правило, це досить вигідно. Хоча токени видаються не одразу, а частинами. як правило протягом року або півроку.

Умовно кажучи, вкладаючи 10$ ви отримуєте через певний час якусь кількість токенів (які зазвичай недооцінені) на 20$. І в момент їхнього лістингу на біржі продаєте в перші 5 – 10 хвилин. У піку зростання.

У цьому відношенні дуже вигідно, коли AIRDROP відбувається на біржі. Яка випускає свій токен, який потім використовується для торгівлі на біржі та оплати комісій. (Наприклад, на binance це BNB ). Так ось у момент лістингу токена на своїй біржі він зазвичай у перші 5 хвилин торгів дорожчає в десятки разів. Оскільки біржа викуповує ці токени. Викуповує (як правило для спалювання, щоб підняти ціну) тому що основне завдання цих токенів було залучити нових користувачів до проекту. І на початку торгів можна нормально заробити.

Зараз якраз на горизонті з’явився цікавий AIRDROP нової української біржі QMALL . Тож якщо комусь цікаво, то можуть взяти участь. У цьому AIRDROP можна отримати токени QML за виконання простих дій. Які можна буде почати продувати 15.02.2022. Детальніше можна подивитися тут

Всі удачі та будьте обережні при інвестуванні в крипту.

Нова ера інвестування

інвестування

Найкраща порада, якій можна дати 18-річному: ігноруй зовнішній шум і зверни увагу всередину.

Це вірно з низки причин:

По-перше, поки ти не заробив грошей, неможливо інвестувати в ринок акцій/облігацій/нерухомості, індивідуальний пенсійний план чи криптовалюту.

По-друге, сума, яку ти можеш інвестувати, значною мірою залежить від того, скільки грошей ти здатний заробити. Нехтувати власною здатністю заробляти – значить ставити віз попереду коня. За інших рівних людей, що заробляє $5000 на місяць, може дозволити собі інвестувати більше грошей, ніж той, хто отримує лише $3000.

По-третє, чим ти молодший, тим простіше тобі набути нових навичок. Ні, вікно не закривається ніколи. Але до 25 років людський мозок ще не остаточно сформувався, і чим ти молодший, тим менше у тебе обов’язків. У суперечці про те, хто швидше навчиться програмувати, я в 99 випадках зі 100 поставлю на 18-річного молодика, який щойно закінчив школу, а не на 35-річну одиноку матір.

По-четверте, інвестуючи в себе, ти виключаєш контрагентський ризик. Тобто ти розглядаєш себе як актив, який хочеш вкласти свій капітал. Так тобі не потрібно турбуватися, що акції компанії обваляться, що тобі не повернуть позику і т.п.

І список можна продовжувати.

Уоррен Баффетт – людина, яка пристойно заробила на інвестиціях, – найкраще резюмувала:

«Інвестувати у себе – найкраще, що можна зробити. Якщо в тебе є таланти, ніхто не зможе в тебе їх забрати».

Я згоден із паном Баффеттом.

У абсолютно нормальному світі моя інвестиційна теза була б пряма як палиця і надійна як швейцарський годинник:

Насамперед інвестуй у власну здатність заробляти. Купи житло за власний кошт (не в іпотеку), щоб завжди мати дах над головою. Максимально застрахуйся від ризиків. Май великий готівковий баланс на випадок майбутньої невизначеності та сприятливих можливостей. Тримай золото та срібло, але не надто багато. Реінвестуй невитрачений прибуток у те, над чим у тебе найбільше контролю, – власний бізнес. І щомісяця вкладай у S&P 500 лише стільки, скільки можеш дозволити собі втратити, щоб у неспокійні часи можна було залишити ці інвестиції у спокої та дозволити їм робити те, що їм виходить найкраще: нарощувати вартість.

Я не надто люблю ризик. Від однієї вже думки про те, що все, заради чого я працював, може впасти, мені стає не по собі. Тож я дуже високо ціную можливість добре спати вночі.

АЛЕ!

На даний момент я повністю відкинув цю тезу.

Цьому є дві основні причини:

1. Ми НЕ живемо у абсолютно нормальному світі – особливо зараз. Хоч як парадоксально, те, що світ не нормальний, – це нормально. Але наша реакція на цю ненормальність зовсім не нормальна.

2. Зустрівшись із інвестиційною можливістю тисячоліття, слід відкинути розхожу мудрість.

1. Світ нормальний; наша реакція на нього – ні

З часу фінансової кризи 2007 р. ми наражаємося на кредитно-грошовий експеримент. Але експеримент цей не новий. Упродовж історії його проводили у багатьох економіках, і це завжди без винятку закінчувалося дуже погано.

Завжди. Без винятку.

Стати першими в історії, кому вдасться вийти з експерименту краще, ніж до нього, чи хоча б не гірше – найбільший виклик.

Чи це можливо?

Так, чорт забирай.

Чи це ймовірно?

Ні. І історія це підтверджує.

Дозвольте спершу пояснити поточну ситуацію за допомогою простої аналогії.

Дак Прескотт

Ось фотографія усміхненого Дака Прескотта – накачаного знеболюючим – в очікуванні операції після страшної травми кісточки, отриманої у грі в американський футбол. Якщо коротко, то у нього зі шкіри стирчали кістки.

Мені хотілося б порівняти між Даком Прескоттом (у момент, коли було зроблено цю фотографію) і американською економікою з часу фінансової кризи 2007 р.:

Американська економіка нагадує Дака Прескотта, якому лікарі дали морфін, щоби притупити біль. Але якщо не провести належне лікування (операцію), тому що він постійно посміхається завдяки медикаментам, то зростає ймовірність, що його рана запалиться, йому доведеться ампутувати ногу і зрештою він помре.

Так само Федеральна резервна система (ФРС) здатна накачати економіку морфіном (тобто готівкою), щоб притупити біль (тобто запобігти рецесії, підтримати Уолл-стріт і т. д.). Але якщо досить довго нехтувати належним лікуванням (тобто не дозволяти неприбутковим бізнесам банкрутуватись, щоб їм на зміну прийшли нові), то історія каже, що валюта такої економіки в процесі сильно знеціниться.

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

Або, як одного разу сказав Каньє Вест:

«План був пити, доки біль не пройде, – але що гірше: біль чи похмілля?»

Ось як розгортається цей план для основних фіатних валют світу:

Як можна бачити, всі ключові валюти – американський долар, японська єна, британський фунт стерлінгів, євро тощо – колись були прив’язані до золота. Але у разі, коли прив’язку скасовували і дозволяли центральним банкам збільшувати грошову масу, валюти рано чи пізно починали рухатися убік нуля.

Зазвичай це згубно позначається на глобальних резервних валютах. Ось що відбувалося щоразу починаючи з 1450:

Статус резервної валюти є непостійним.
Статус резервної валюти є непостійним. Джерело: Azizonomics

Португалія. Іспанія Нідерланди. Франція. Великобританія…

Чи можуть США стати наступними у списку? Чи це здається надто неймовірним?

Подобається вам чи ні, але саме до цього все йде. Мені не хотілося б ставити проти США, але наші ін’єкції морфіну з 2007 р. сильно збільшилися – особливо в останні два роки:

  • ФРС з 2008 по 2014 роки. провела три кількісні пом’якшення, фактично «надрукувавши» $4 трильйони за сім років.
  • Наприкінці 2018 р. ФРС вирішила підняти відсоткові ставки. Це робиться, щоб забезпечити стійке економічне зростання та запобігти інфляції. Часто це сигналізує, що у горизонті з’явилася рецесія – обов’язкова фаза боргового циклу. Однак на початку 2019 р. ФРС швидко вирішила змінити курс. Це вказувало на те, що США продовжать збільшувати свій борговий тягар, тобто вирішення проблеми відкладено у довгу скриньку. Як наслідок, наступне похмілля (тобто рецесія) буде жорсткішим.
  • Викуп власних акцій – сумнівна практика великих корпорацій та банків – з 2010 р. становив $500 млрд. Викуп акцій – це як зворотні дивіденди: так CEO збагачуються за рахунок акціонерів. На жаль, багато з цих корпорацій знову отримали допомогу в рамках першого плану стимулювання у 2020 році.
  • У вересні 2019 року ми побачили дивну активність на ринку РЕПО. По суті, ставка кредитування овернайт між банками сильно підскочила. ФРС була настільки стурбована, що влила $278 млрд., щоб банки змогли задовольнити свої потреби. Вона зробила щось подібне вперше з часу фінансової кризи 2007 року.
  • В останні місяці 2019 р. ми постійно чули, як CEO залишають свої посади.
  • Зрештою, у лютому 2020 р. американська економіка офіційно увійшла до рецесії. “Великим каталізатором” послужив COVID-19. Це поклало край найтривалішої економічної експансії історія США з 1854 р.

Очевидно, що серйозні тріщини економіки були ще до того, як пандемія все обрушила. І ТОДІ ФРС втрутилася із безпрецедентно великим пакетом стимулювання. ФРС створила $7 ТРЛН, які раніше не існували. Рано чи пізно нам доведеться їх повернути.

Але майте на увазі таке:

Скорочення випадковості/волатильності (за допомогою морфіну та друкування грошей) робить систему загалом (економіку) більш крихкою.

На щастя, ми маємо рішення для цього безумства.

bitcoin

2. Інвестиційна можливість тисячоліття

Головна інвестиційна можливість вашого життя – вкластися в себе та власні таланти, як радить Уоррен Баффетт.

Але що має отримати пріоритет, якщо на нас впаде інвестиційна спроможність тисячоліття?

Іншими словами, що довговічніше: людське життя, що в середньому у світі триває 72,6 року, або ощадна технологія, яка може проіснувати наступні 1000 років?

У світі, де значна частина населення страждає від надлишку:

  • ожиріння через занадто велику кількість їжі;
  • інфекцій, що швидко поширюються, через гіперглобалізацію і сильну взаємопов’язаність;
  • гіперінфляції через те, що жадібні центральні планувальники зловживають контролем над грошовою масою.

…наступним кроком буде рідкість і самодостатність.

У світі, де невизначеність та занепокоєння знаходяться на історичному піку:

  • Чи відправить роботодавець мене у неоплачувану відпустку чи звільнить?
  • Коли розподілятиметься наступний пакет стимулювання?
  • Коли ми матимемо вакцину і коли ми повернемося до колишнього життя?

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

І у світі, де майнова нерівність поширена більше, ніж будь-коли, урядові бюрократи, як і раніше, показують пальцями на багатих, а не на себе, адже це вони безвідповідально розпоряджаються друкарським верстатом та витратами. Дозвольте коротко пояснити:

Податкові ставки визначаються з урахуванням короткого тимчасового проміжку і відбивають у точності багатство. Уявіть на хвилинку, що ви власник малого бізнесу, якому дев’ять років важко вдавалося зводити кінці з кінцями. Але десятий рік несподівано виявився успішним – можливо достатньо, щоб компенсувати кілька важких років. Але як тільки ви подумали, що впіймали удачу, податки стирають значну частину вашої компенсації за те, що ви так довго ледве виживали. А наступного року урядові бюрократи ще й змушують вас на кілька місяців закрити свій бізнес через пандемію, тоді як самі вони, як і раніше, отримують зарплату.

Тим часом, ті ж таки бюрократи запустили друкарський верстат на повну котушку. Новостворені гроші спочатку опиняються у руках фінансових інститутів та комерційних банків. Як наслідок, вони можуть придбати більше товарів, послуг та активів за ще відносно низькими цінами. Потім, коли ці гроші «просочуються» вниз економічною драбиною, ці активи купує більше людей, і інвестиції фінансових інститутів, які купили «дешево», зростають у вартості. У той же час найбідніші члени суспільства спостерігають, як ціни на повсякденні товари зростають ще до того, як вони встигли отримати свій шматок нового пирога, – вони не можуть дозволити собі купити стільки, як раніше, тому що за ту ж кількість продуктів конкурує більше доларів. Таким чином, з одного боку, багаті стають ще багатшими, а з іншого, бідні стають ще біднішими.

gold
Графік 1917-2012 років. Момент скасування Річардом Ніксоном прив’язки до золотого стандарту та показник зростання доходів. Джерело: Zero Hedge

Відколи був скасований золотий стандарт і друкарському верстату дозволили працювати на повну котушку, 1% найбагатших у США висмоктував усе багатство з 90% найбідніших.

Біткойн здатний все це виправити .

  • Він децентралізований – він нікому не належить, але брати у ньому можуть все.
  • Він незмінний – ніхто не може створити більше біткойнів з повітря і витратити з безрозсудною легкістю.
  • Його пропозиція звичайно рідкісна – ніхто не може зробити свій шматок “пирога багатства” більше за рахунок вашого.
  • Емісія його пропозиції відома заздалегідь – він цінує прозорість та верифікацію на противагу «повному визнанню та довірі Казначейству США».

…І головне, Біткойн дозволяє нам довіритися людству замість 12 людей похилого віку в перуках (членів Федерального комітету з операцій на відкритому ринку ФРС).

У 1879 р. Верховний суд США ухвалив, що держава має бути недвозначно відокремлена від церкви. Час зробити те саме з грошима.

Чому я майже довіряю Біткойну більше, ніж собі

Я нікому – НІКОМУ – не довіряю більше, ніж собі.

Ніхто не знає мене, не цікавиться мною і не вірить у мене так, як я сам. Якби я думав інакше, то сумнівався б, чи варто взагалі жити.

Тим не менш, людство стоїть на другому місці з невеликим відривом – я майже довіряю йому більше, ніж собі. Природа оптимізує все під ціле (тобто людство), а чи не під індивіда. І з цієї ж причини людство, як і будь-яка інша система, згодом еволюціонує та адаптується:

  • Авіація після кожної авіакатастрофи стає безпечнішою.
  • М’язи після напруги, розриву та відновлення стають сильнішими.
  • Ми еволюціонували від неандертальців з низьким IQ до прямоходячого «хомо сапієнс» з віддаленим великим пальцем і корою головного мозку більше, ніж у будь-якої іншої тварини, що нині живе.

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

Саме ми, прості люди, щодня ризикуємо власною шкірою. Ми визначаємо правила. Ми еволюціонуємо. І оскільки Біткойн дозволяє людям взяти долю у свої руки, він цілком може бути нашою другою найкращою інвестиційною можливістю.

Джерело