Diferença entre declarativo e imperativo em React.js?


101

Recentemente, tenho estudado muito sobre a funcionalidade e as formas de usar a biblioteca JavaScript do Facebook React.js. Quando se fala de suas diferenças com o resto do mundo JavaScript muitas vezes os dois estilos de programação declarativee imperativesão mencionada.

Qual é a diferença entre os dois?


23
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 escreveu um longo artigo sobre isso com alguns bons exemplos.
Ian Dunn

Por que adicionar uma resposta longa como um comentário? ..
Alex

1
O link acima está correto, mas uma barra final incluída no link causa 404. latentflip.com/imperative-vs-declarative
James Yoo

Respostas:


173

Um estilo declarativo, como o que react tem, permite que você controle o fluxo e o estado de seu aplicativo dizendo "Deve ser assim". Um estilo imperativo inverte isso e permite que você controle seu aplicativo dizendo "Isso é o que você deve fazer".

O benefício do declarativo é que você não se atola nos detalhes de implementação da representação do estado. Você está delegando o componente organizacional de manter as visualizações do aplicativo consistentes, então você só precisa se preocupar com o estado.

Imagine que você tem um mordomo, que é uma espécie de metáfora para uma estrutura. E você gostaria de fazer o jantar. Em um mundo imperativo, você diria a eles passo a passo como fazer o jantar. Você deve fornecer estas instruções:

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

Em um mundo declarativo, você simplesmente descreveria o que deseja

I want dinner with chicken.

Se o seu mordomo não souber fazer frango, você não poderá agir de forma declarativa. Assim como se o Backbone não sabe como se transformar para fazer uma determinada tarefa, você não pode simplesmente dizer a ele para fazer essa tarefa. O React pode ser declarativo porque "sabe fazer frango", por exemplo. Em comparação com o Backbone, que só sabe fazer interface com a cozinha.

Ser capaz de descrever o estado reduz drasticamente a área de superfície para bugs, o que é uma vantagem. Por outro lado, você pode ter menos flexibilidade em como as coisas ocorrem porque está delegando ou abstraindo a forma como implementa o estado.


81

Imagine um componente de IU simples, como um botão "Curtir". Quando você toca nele, ele fica azul se antes era cinza e cinza se era azul.

A maneira imperativa de fazer isso seria:

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

Basicamente, você deve verificar o que está atualmente na tela e lidar com todas as alterações necessárias para redesenhar com o estado atual, incluindo desfazer as alterações do estado anterior. Você pode imaginar como isso pode ser complexo em um cenário do mundo real.

Em contraste, a abordagem declarativa seria:

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

Como a abordagem declarativa separa as questões, esta parte dela só precisa lidar com a aparência da IU em um estado específico e, portanto, é muito mais simples de entender.


22

Esta é uma ótima analogia:

* Uma resposta imperativa : saia pela saída norte do estacionamento e vire à esquerda. Pegue a I-15 sul até chegar à saída da Bangerter Highway. Vire à direita na saída como se estivesse indo para a Ikea. Siga em frente e vire à direita no primeiro semáforo. Continue até o próximo semáforo e depois vire à esquerda. Minha casa é # 298.

Uma resposta declarativa : Meu endereço é 298 West Immutable Alley, Draper Utah 84020 *

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


18

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

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

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 .


8

O código imperativo instrui o JavaScript sobre como ele deve executar cada etapa. Com o código declarativo, dizemos ao JavaScript o que queremos fazer e deixamos o JavaScript cuidar da execução das etapas.

React é declarativo porque escrevemos o código que queremos e React é responsável por pegar nosso código declarado e realizar todas as etapas de JavaScript / DOM para nos levar ao resultado desejado.


5

Um paralelo da vida real no mundo imperativo seria entrar em um bar para tomar uma cerveja e dar as seguintes instruções ao barman:

- Pegue um copo da prateleira

- Coloque o copo na frente da corrente de ar

- Puxe a alça para baixo até que o copo esteja cheio

- Passe-me o copo.

No mundo declarativo, em vez disso, você diria apenas: "Cerveja, por favor."

A abordagem declarativa de pedir uma cerveja pressupõe que o barman sabe como servi-la, e esse é um aspecto importante do funcionamento da programação declarativa.

Na programação declarativa, os desenvolvedores apenas descrevem o que desejam alcançar e não há necessidade de listar todas as etapas para que isso funcione.

O fato de o React oferecer uma abordagem declarativa torna-o fácil de usar e, consequentemente, o código resultante é simples, o que geralmente leva a menos bugs e mais facilidade de manutenção.

Como o React segue um paradigma declarativo, não há necessidade de dizer a ele como interagir com o DOM; você apenas DECLARA o que deseja ver na tela e o React faz o trabalho por você.



0
  • Declarativo permite que você controle todas as visualizações. (como gestão de estado)
  • o Imperativo permite que você controle a visualização. (como $ (this))

0

Vou começar com uma analogia: eu tenho dois carros, em meus dois carros eu quero que a temperatura dentro do meu carro seja a temperatura ambiente normal ~ 72 ° F. No primeiro carro (mais antigo), há dois botões para controlar a temperatura (1 botão para controlar a temperatura e 1 botão para controlar o fluxo de ar). Quando fica muito quente, tenho que ajustar o primeiro botão para diminuir a temperatura e talvez mudar o fluxo de ar) e vice-versa se estiver muito frio. Este é um trabalho imperativo! Tenho que controlar os botões sozinho. No meu segundo carro (mais recente), posso definir / declarar a temperatura. O que significa que não preciso mexer nos botões para ajustar a temperatura que meu carro sabe que declaro / configurei para 72 ° F e meu carro fará o trabalho necessário para chegar a esse estado.

O React é o mesmo, você declara a marcação / template e a estatística e então o React faz o trabalho obrigatório para manter o DOM sincronizado com o seu aplicativo.

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

Em vez de usar .addEventListener()para configurar o tratamento de eventos, declaramos o que queremos. Quando o botão é clicado, ele executa a activateTeleporterfunção.


0

Declarativo vs Imperativo

Programação declarativa é como pedir a um amigo para pintar sua casa. Você não se importa como eles limpam, com que cor eles usam para pintar, quantos recursos eles usaram para completá-lo.

//Declarative For Searching element from an array
  array.find(item)

O oposto de declarativo é imperativo. Um exemplo comum de abordagem imperativa é você dizer a seu amigo exatamente o que fazer para pintar sua casa.

  • Lave a casa com detergente.
  • Use tinta Narolac ou tinta asiática
  • Pinte o telhado com a cor verde.
  • Faça com que 3 membros contratem, etc.

// Imperative Algo

def imperative_search(array, item)
  for i in array do
    if i == item
      return item
    end
  end
  return false
end
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.