¿Diferencia entre declarativo e imperativo en React.js?

97

Recientemente he estado estudiando mucho sobre la funcionalidad y las formas de usar la biblioteca de JavaScript de Facebook React.js. Cuando se habla de sus diferencias con el resto del mundo de JavaScript, a menudo se mencionan los dos estilos de programación declarativey imperative.

¿Cuál es la diferencia entre ambos?

Sócrates
fuente
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
Tyler McGinnis escribió un largo artículo sobre esto con algunos buenos ejemplos.
Ian Dunn
¿Por qué agregar una respuesta larga como comentario? ..
Alex
1
El enlace anterior es correcto, pero una barra inclinada incluida en el enlace causa 404. latentflip.com/imperative-vs-declarative
James Yoo

Respuestas:

167

Un estilo declarativo, como el que tiene react, le permite controlar el flujo y el estado de su aplicación diciendo "Debería verse así". Un estilo imperativo le da la vuelta a eso y le permite controlar su aplicación diciendo "Esto es lo que debe hacer".

El beneficio de la declaración es que no se empantana en los detalles de implementación de la representación del estado. Está delegando el componente organizativo de mantener la coherencia de las vistas de su aplicación, por lo que solo tiene que preocuparse por el estado.

Imagina que tienes un mayordomo, que es una especie de metáfora de un marco. Y te gustaría hacer la cena. En un mundo imperativo, les dirías paso a paso cómo preparar la cena. Tienes que proporcionar estas instrucciones:

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

En un mundo declarativo, simplemente describiría lo que quiere

I want dinner with chicken.

Si su mayordomo no sabe cómo hacer pollo, entonces no puede operar en un estilo declarativo. Al igual que si Backbone no sabe cómo mutarse para realizar una determinada tarea, no puede simplemente decirle que haga esa tarea. React puede ser declarativo porque "sabe hacer pollo", por ejemplo. En comparación con Backbone, que solo sabe interactuar con la cocina.

Ser capaz de describir el estado reduce drásticamente la superficie de los insectos, lo cual es un beneficio. Por otro lado, es posible que tenga menos flexibilidad en cómo ocurren las cosas porque está delegando o abstrayendo cómo implementa el estado.

Nathan Hagen
fuente
78

Imagine un componente de interfaz de usuario simple, como un botón "Me gusta". Cuando lo toca, se vuelve azul si anteriormente era gris y gris si antes era azul.

La forma imperativa de hacer esto sería:

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

Básicamente, debe verificar lo que está actualmente en la pantalla y manejar todos los cambios necesarios para volver a dibujarlo con el estado actual, incluido deshacer los cambios del estado anterior. Puede imaginar lo complejo que podría ser esto en un escenario del mundo real.

En contraste, el enfoque declarativo sería:

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

Debido a que el enfoque declarativo separa las preocupaciones, esta parte solo necesita manejar cómo debería verse la interfaz de usuario en un estado específico y, por lo tanto, es mucho más simple de entender.

Ahmed Eid
fuente
21

Esta es una gran analogía:

* Una respuesta imperativa : Salga por la salida norte del estacionamiento y gire a la izquierda. Tome la I-15 sur hasta llegar a la salida de la autopista Bangerter. Gire a la derecha en la salida como si fuera a Ikea. Siga recto y gire a la derecha en el primer semáforo. Continúe hasta el siguiente semáforo y luego gire a la izquierda. Mi casa es el número 298.

Una respuesta declarativa : Mi dirección es 298 West Immutable Alley, Draper Utah 84020 *

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

serkan
fuente
18

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);

  // 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);
  ...
}

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 .

fuerza motriz
fuente
6

El código imperativo instruye a JavaScript sobre cómo debe realizar cada paso. Con código declarativo, le decimos a JavaScript lo que queremos hacer y dejamos que JavaScript se encargue de realizar los pasos.

React es declarativo porque escribimos el código que queremos y React está a cargo de tomar nuestro código declarado y realizar todos los pasos de JavaScript / DOM para llegar al resultado deseado.

Nikhil
fuente
5

Un paralelo de la vida real en el mundo imperativo sería entrar en un bar por una cerveza y darle las siguientes instrucciones al barman:

--Toma un vaso del estante

--Ponga el vaso delante del calado

- Tire del mango hacia abajo hasta que el vaso esté lleno

--Pásame el vaso.

En el mundo declarativo, en cambio, simplemente diría: "Cerveza, por favor".

El enfoque declarativo de pedir una cerveza asume que el bartender sabe cómo servir una, y ese es un aspecto importante del funcionamiento de la programación declarativa.

En la programación declarativa, los desarrolladores solo describen lo que quieren lograr y no es necesario enumerar todos los pasos para que funcione.

El hecho de que React ofrece un enfoque declarativo lo hace fácil de usar y, en consecuencia, el código resultante es simple, lo que a menudo conduce a menos errores y más facilidad de mantenimiento.

Dado que React sigue un paradigma declarativo, y no es necesario decirle cómo interactuar con el DOM; simplemente DECLARA lo que quiere ver en la pantalla y React hace el trabajo por usted.

Yilmaz
fuente
0

Comenzaré con una analogía: tengo dos autos, en mis dos autos quiero que la temperatura dentro de mi auto sea la temperatura ambiente normal ~ 72 ° F. En el primer automóvil (más antiguo), hay dos perillas para controlar la temperatura (1 perilla para controlar la temperatura y 1 perilla para controlar el flujo de aire). Cuando hace demasiado calor, tengo que ajustar la primera perilla para bajar la temperatura y tal vez cambiar el flujo de aire) y viceversa si hace demasiado frío. ¡Este es un trabajo imperativo! Tengo que manejar las perillas yo mismo. En mi segundo automóvil (más nuevo), puedo establecer / declarar la temperatura. Lo que significa que no tengo que manipular las perillas para ajustar la temperatura que mi automóvil sabe, la declaro / configuro a 72 ° F y mi automóvil hará el trabajo imperativo para llegar a ese estado.

React es lo mismo, declaras el marcado / plantilla y la estadística, luego React hace el trabajo imperativo para mantener el DOM sincronizado con tu aplicación.

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

En lugar de usar .addEventListener()para configurar el manejo de eventos, declaramos lo que queremos. Cuando se hace clic en el botón, ejecutará la activateTeleporterfunción.

Ryan Efendy
fuente
-1
  • Declarativo le permite controlar todas las vistas. (como gestión estatal)
  • el imperativo te permite controlar la vista. (como $ (esto))
Naing Min Khant
fuente