Лучше всего сравнить 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);
updateTotalPrice();
...
}
updateVolume(volume) {
$("#volume-label").val(volume);
$("#volume-label").toggleClass('high', volume > 1000);
$("#volume-label").toggleClass('low', volume < 1000);
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, используя свой алгоритм Virtual DOM Diffing .
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.