Es mejor comparar React (declarativo) y JQuery (imperativo) para mostrarle las diferencias.
En React, solo necesita describir el estado final de su IU en el render()
método, sin preocuparse por cómo pasar del estado de IU anterior al nuevo estado de IU. P.ej,
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 otro lado, JQuery requiere que realice la transición de su estado de interfaz de usuario de manera imperativa, por ejemplo, seleccionando los elementos de la etiqueta y actualizando su texto y 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);
...
}
En el escenario del mundo real, habrá muchos más elementos de la interfaz de usuario para actualizar, además de sus atributos (por ejemplo, estilos CSS y detectores de eventos), etc. Si hace esto imperativamente usando JQuery, se volverá complejo y tedioso; es fácil olvidarse de actualizar algunas partes de la interfaz de usuario u olvidarse de eliminar los controladores de eventos antiguos (provocar pérdidas de memoria o disparos del controlador varias veces), etc. Aquí es donde ocurren los errores, es decir, el estado de la interfaz de usuario y el estado del modelo están fuera de sincronizar.
Los estados no sincronizados nunca sucederán con el enfoque declarativo de React, porque solo necesitamos actualizar el estado del modelo, y React es responsable de mantener la interfaz de usuario y los estados del modelo sincronizados.
- Bajo el gancho, React actualizará todos los elementos DOM cambiados usando código imperativo.
También puede leer mi respuesta para ¿Cuál es la diferencia entre programación declarativa e imperativa? .
PD: del ejemplo anterior de jQuery, puede pensar qué pasaría si colocamos todas las manipulaciones DOM en un updateAll()
método y lo llamamos cada vez que cambia alguno de los estados de nuestro modelo, y la interfaz de usuario nunca estará desincronizada. Tiene razón, y esto es efectivamente lo que hace React, la única diferencia es que jQuery updateAll()
causará muchas manipulaciones DOM innecesarias, pero React solo actualizará los elementos DOM cambiados usando su Algoritmo de diferenciación 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.