Різниця між декларативним та імперативним у React.js?


97

Нещодавно я багато вивчав функціонал та способи використання бібліотеки Facebook JavaScript React.js. Говорячи про свої відмінності в іншій частині світу JavaScript часто двох стилів програмування declarativeі imperativeякі згадувалося.

Яка різниця між ними?


22
latentflip.com/imperative-vs-declarative Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it.
rickyduck

4
Тайлер Макгінніс написав про це довгу статтю з кількома хорошими прикладами.
Ян Данн,

Навіщо додавати довгу відповідь як коментар? ..
Алекс,

1
Вищевказане посилання є правильним, але кінцева скісна
James Yoo

Відповіді:


167

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

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

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

Go to the kitchen
Open fridge
Remove chicken from fridge
...
Bring food to the table

У декларативному світі ви просто описали б те, що хочете

I want dinner with chicken.

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

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


78

Уявіть простий компонент інтерфейсу, наприклад, кнопку "Подобається". Коли ви натискаєте на нього, він стає синім, якщо він раніше був сірим, і сірим, якщо раніше був синім.

Обов’язковим способом цього буде:

if( user.likes() ) {
    if( hasBlue() ) {
        removeBlue();
        addGrey();
    } else {
        removeGrey();
        addBlue();
    }
}

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

На відміну від цього, декларативний підхід буде таким:

if( this.state.liked ) {
    return <blueLike />;
} else {
    return <greyLike />;
}

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


21

Це чудова аналогія:

* Обов’язкова відповідь : Вийдіть із північного виїзду на стоянку та поверніть ліворуч. Сідайте на південь I-15, поки не дійдете до виїзду на шосе Бангертера. Поверніть праворуч від виїзду, ніби їдете до Ікеї. Йдіть прямо і поверніть праворуч при першому світлі. Продовжуйте рух через наступне світло, тоді поверніть на наступне ліворуч. Мій будинок №298.

Декларативна відповідь : моя адреса - 298 West Immutable Alley, Draper Utah 84020 *

https://tylermcginnis.com/imperative-vs-declarative-programming/


18

Найкраще порівняти React (декларативний) та JQuery (імперативний), щоб показати вам відмінності.

У React вам потрібно лише описати остаточний стан вашого інтерфейсу в render()методі, не турбуючись про те, як перейти з попереднього стану інтерфейсу в новий стан інтерфейсу. Наприклад,

render() {
  const { price, volume } = this.state;
  const totalPrice = price * volume;

  return (
    <div>
      <Label value={price} className={price > 100 ? 'expensive' : 'cheap'} ... />
      <Label value={volume} className={volume > 1000 ? 'high' : 'low'} ... />
      <Label value={totalPrice} ... />
      ...
    </div>
  )
}

З іншого боку, JQuery вимагає від вас імперативного переходу стану вашого інтерфейсу, наприклад, вибору елементів мітки та оновлення їх тексту та CSS:

updatePrice(price) {
  $("#price-label").val(price);
  $("#price-label").toggleClass('expansive', price > 100);
  $("#price-label").toggleClass('cheap', price < 100);

  // also remember to update UI depending on price 
  updateTotalPrice();
  ... 
}

updateVolume(volume) {
  $("#volume-label").val(volume);
  $("#volume-label").toggleClass('high', volume > 1000);
  $("#volume-label").toggleClass('low', volume < 1000);
  
  // also remember to update UI depending on volume
  updateTotalPrice();
  ... 
}

updateTotalPrice() {
  const totalPrice = price * volume;
  $("#total-price-label").val(totalPrice);
  ...
}

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

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

  • Під гачком React оновить всі змінені елементи DOM, використовуючи імперативний код.

Ви також можете прочитати мою відповідь на тему: Яка різниця між декларативним та імперативним програмуванням? .

PS: зверху на прикладі jQuery, ви можете подумати, що, якщо ми покладемо всі маніпуляції з DOM у updateAll()метод, і будемо викликати його кожного разу, коли будь-який стан нашої моделі змінюється, і інтерфейс користувача ніколи не буде несинхронізованим. Ви маєте рацію, і це фактично те, що робить React, єдина різниця полягає в тому, що jQuery updateAll()спричинить багато непотрібних маніпуляцій DOM, але React буде оновлювати лише змінені елементи DOM, використовуючи свій віртуальний алгоритм DOM Diffing .


6

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

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


5

Реальною паралеллю в імперативному світі було б зайти в бар за пивом і дати наступні вказівки бармену:

- Візьміть склянку з полиці

- Поставте склянку перед протягом

- Потягніть ручку, доки склянка не заповниться

- Передай мені келих.

Натомість у декларативному світі ви просто сказали б: "Пиво, будь ласка".

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

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

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

Оскільки React слідує декларативній парадигмі, і немає необхідності розповідати йому, як взаємодіяти з DOM; ви просто ДЕКЛАРУЙТЕ те, що хочете бачити на екрані, і React виконує цю роботу за вас.


1

Декларативне програмування - це парадигма програмування ... яка виражає логіку обчислення без опису його потоку управління.

Імперативне програмування - це парадигма програмування, яка використовує твердження, що змінюють стан програми.

посилання на посилання: - https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2


0

Почну з аналогії: у мене є дві машини, у своїх двох я хочу, щоб температура в моїй машині була нормальною кімнатною температурою ~ 72 ° F. У першому (старшому) вагоні є дві ручки для регулювання температури (1 ручка для регулювання температури та 1 ручка для регулювання потоку повітря). Коли стає занадто жарко, я повинен відрегулювати першу ручку, щоб знизити температуру і, можливо, змінити потік повітря) і навпаки, якщо занадто холодно. Це обов’язкова робота! Я повинен керувати ручками сам. У своєму другому (новішому) автомобілі я можу встановити / оголосити температуру. Що означає, що мені не потрібно возитися з ручками, щоб регулювати температуру, яку мій автомобіль знає, що я заявляю / встановлюю її на 72 ° F, і моя машина виконає обов’язкову роботу, щоб дійти до цього стану.

React той самий, ви оголошуєте розмітку / шаблон і stat, тоді React виконує обов’язкову роботу, щоб підтримувати DOM в синхронізації з вашим додатком.

<button onClick={activateTeleporter}>Activate Teleporter</button>

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


-1
  • Декларація дозволяє контролювати весь перегляд. (наприклад, як державне управління)
  • імператив дозволяє контролювати оточення. (наприклад, як $ (this))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.