É melhor comparar React (declarativo) e JQuery (imperativo) para mostrar as diferenças.
No React, você só precisa descrever o estado final da sua IU no render()
método, sem se preocupar em como fazer a transição do estado anterior da IU para o novo estado da IU. Por exemplo,
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>
)
}
Por outro lado, JQuery requer que você faça a transição de seu estado de IU imperativamente, por exemplo, selecionando os elementos do rótulo e atualizando seu texto e 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);
...
}
No cenário do mundo real, haverá muitos mais elementos de IU a serem atualizados, além de seus atributos (por exemplo, estilos CSS e ouvintes de eventos), etc. Se você fizer isso obrigatoriamente usando JQuery, isso se tornará complexo e tedioso; é fácil esquecer de atualizar algumas partes da IU ou de remover manipuladores de eventos antigos (causar vazamento de memória ou o manipulador dispara várias vezes), etc. É aqui que os bugs acontecem, ou seja, o estado da IU e o estado do modelo estão fora de sincronizar.
Os estados fora de sincronia nunca acontecerão com a abordagem declarativa do React, porque só precisamos atualizar o estado do modelo, e o React é responsável por manter a IU e os estados do modelo em sincronia.
- No gancho, o React atualizará todos os elementos DOM alterados usando código imperativo.
Você também pode ler minha resposta para Qual é a diferença entre programação declarativa e imperativa? .
PS: do exemplo acima do jQuery, você pode pensar o que aconteceria se colocássemos todas as manipulações DOM em um updateAll()
método e o chamasse sempre que qualquer um de nossos estados de modelo mudasse, e a IU nunca ficaria fora de sincronia. Você está correto, e isso é efetivamente o que o React faz, a única diferença é que o jQuery updateAll()
causará muitas manipulações DOM desnecessárias, mas o React só atualizará os elementos DOM alterados usando seu Algoritmo de Diffing do DOM Virtual .
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.