Prós e contras do React do Facebook vs. Componentes da Web (polímero)


521

Quais são os principais benefícios do React do Facebook sobre as próximas especificações dos componentes da Web e vice-versa (ou talvez uma comparação mais maçãs com maçãs seja a biblioteca Polymer do Google )?

De acordo com esta palestra da JSConf na UE e a página inicial do React, os principais benefícios do React são:

  • Desacoplamento e aumento da coesão usando um modelo de componente
  • Abstração, Composição e Expressividade
  • DOM virtual e eventos sintéticos (o que basicamente significa que eles reimplementaram completamente o DOM e seu sistema de eventos)
    • Permite coisas modernas de eventos HTML5 no IE 8
    • Renderização do lado do servidor
    • Testabilidade
    • Ligações a SVG, VML e <canvas>

Quase tudo o que foi mencionado está sendo integrado aos navegadores de forma nativa por meio dos Web Components, exceto este conceito virtual de DOM (obviamente). Posso ver como o DOM virtual e os eventos sintéticos podem ser benéficos hoje para oferecer suporte a navegadores antigos, mas não está descartando uma grande quantidade de código de navegador nativo, como se você se matasse a longo prazo? No que diz respeito aos navegadores modernos, isso não representa muita sobrecarga / reinvenção desnecessária da roda?

Aqui estão algumas coisas que acho que o React está faltando e que o Web Components cuidará de você. Corrija-me se eu estiver errado.

  • Suporte nativo ao navegador (leia "garantia de ser mais rápido")
  • Escreva um script em uma linguagem de script, escreva estilos em uma linguagem de estilo, escreva marcação em uma linguagem de marcação.
  • Encapsulamento de estilo usando o Shadow DOM
    • Em vez disso, o React possui isso , o que requer a gravação de CSS em JavaScript. Feio.
  • Encadernação bidirecional

12
Wrt. ligação em dois sentidos. Esse recurso é problemático em escala. Em casos triviais, funciona bem, mas, nos casos do mundo real, você normalmente acha que, para manter o código gerenciável, é necessário um modelo de visualização para vincular, em vez de vincular ao modelo real, o que torna a associação bidirecional muito menos útil do que inicialmente parecia. Eu acho que pode ser uma vantagem do React que ele não forneça ligação bidirecional porque força a arquitetura de fluxo de dados adequada.
Joeri Sebrechts

8
Eu olhei para React, Angular e Knockout. Acho o Knockout o 'mais limpo' em termos de separação de modelos, dados e ligação da interface do usuário. Eu queria gostar de reagir, mas, ao tentar criar uma Combobox simples, percebo que estava escrevendo muito mais código e misturando a lógica de renderização com o modelo de html ... muito mais do que faria usando algo como html / jina2. Parece-me que essas bibliotecas / APIs estão nos movendo para trás, não para frente. A melhor coisa sobre React é a manipulação de dom virtual, mas posso ver isso chegando a outras estruturas estabelecidas mais cedo ou mais tarde.
mike01010

41
Estou muito surpreso (e também satisfeito!) Por esta pergunta não ter sido encerrada como "principalmente baseada em opiniões".
Iconoclast

4
Não é possível escrever "script em uma linguagem de script" e "marcação em uma linguagem de marcação" se você estiver fazendo modelagem de qualquer tipo. Angular, polímero etc. usam um modelo DSL incorporado em HTML. O React usa um modelo DSL incorporado em JS (JSX). O problema com a incorporação de uma DSL em HTML é como estabelecer escopo para obter valores do JS. Isso leva ao complexo sistema de escopo $ da Angular. No JSX, por outro lado, o escopo das variáveis ​​nos modelos é apenas o escopo do JS - acho muito menos confuso.
Andy

3
No momento, os componentes do React (a menos que estejam mal escritos) seriam mais rápidos que o mesmo em qualquer estrutura vinculada ao DOM. A magia dominante e diferente é a USP da reação. O que quero dizer é: por que os navegadores não criariam uma diferença como essa em seu conjunto de recursos nativo? O que os impede, e se nada (os impede), então a liderança do React provavelmente terá vida curta.
fasttrainofthoughts

Respostas:


664

Atualização:  esta resposta parece ser bastante popular, então levei um tempo para limpá-la um pouco, adicionar novas informações e esclarecer algumas coisas que eu achava que não eram suficientemente claras. Comente se você acha que algo mais precisa de esclarecimentos ou atualizações.

A maioria das suas preocupações é realmente uma questão de opinião e preferência pessoal, mas tentarei responder o mais objetivamente possível:

Nativo vs. Compilado

Escreva JavaScript em baunilha JavaScript, escreva CSS em CSS, escreva HTML em HTML.

Naquela época, havia muitos debates sobre se alguém deveria escrever um  Assembly nativo manualmente ou usar uma linguagem de nível superior como C para fazer o compilador gerar o código do Assembly para você. Mesmo antes disso, as pessoas se recusavam a confiar em montadores e preferiam escrever código de máquina nativo manualmente ( e não estou brincando ).

Atualmente, muitas pessoas escrevem HTML em Haml ou Jade , CSS em Sass ou Less e JavaScript em CoffeeScript ou TypeScript . Está lá. Funciona. Algumas pessoas preferem, outras não.

O ponto é que não há nada de fundamentalmente errado em não escrever JavaScript em vanilla JavaScript, CSS em CSS e HTML em HTML. É realmente uma questão de preferência.

DSLs internas vs. externas

 Em vez disso, o encapsulamento de estilo usando o Shadow DOM React possui isso, o que requer a gravação de CSS em JavaScript. Feio.

Bonito ou não, é certamente expressivo. JavaScript é uma linguagem muito poderosa, muito mais poderosa que CSS (mesmo incluindo qualquer um dos pré-processadores CSS). Depende de você preferir DSLs internas ou externas para esse tipo de coisa. Novamente, uma questão de preferência.

(Observação: eu estava falando sobre os estilos embutidos no React que foram mencionados na pergunta original.)

Tipos de DSLs - explicação

Atualização: Lendo minha resposta algum tempo depois de escrevê-la, acho que preciso explicar o que quero dizer aqui. DSL é uma linguagem específica do domínio e pode ser interna (usando a sintaxe da linguagem do host como JavaScript - como, por exemplo, React sem JSX, ou como os estilos embutidos em React mencionados acima) ou pode ser externa (usando uma sintaxe diferente que a linguagem host - como neste exemplo, seria CSS embutido (um DSL externo) dentro do JavaScript).

Pode ser confuso, porque algumas literaturas usam termos diferentes de "interno" e "externo" para descrever esses tipos de DSLs. Às vezes, "incorporado" é usado em vez de "interno", mas a palavra "incorporado" pode significar coisas diferentes - por exemplo, Lua é descrita como "Lua: uma linguagem incorporada extensível", onde incorporado não tem nada a ver com DSL (interno) incorporado (em nesse sentido, é exatamente o oposto - um DSL externo), mas significa que ele está incorporado no mesmo sentido que, digamos, o SQLite é um banco de dados incorporado. Existe até o eLua onde "e" significa "incorporado" em um terceiro sentido - que é destinado a sistemas embarcados! É por isso que não gosto de usar o termo "DSL incorporado" porque coisas como eLua podem ser "DSLs" que são "incorporadas" em dois sentidos diferentes, embora não sejam uma "DSL incorporada"!

Para piorar as coisas, alguns projetos introduzem ainda mais confusão na mistura. Por exemplo. Os modelos de flatiron são descritos como "livres de DSL", enquanto na verdade é apenas um exemplo perfeito de uma DSL interna com sintaxe como:map.where('href').is('/').insert('newurl');

Dito isto, quando escrevi "O JavaScript é uma linguagem muito poderosa, muito mais poderosa que o CSS (mesmo incluindo qualquer um dos pré-processadores CSS). Depende de se você prefere DSLs internas ou externas para esse tipo de coisa. Novamente, uma questão de preferência ". Eu estava falando sobre esses dois cenários:

1:

/** @jsx React.DOM */
var colored = {
  color: myColor
};
React.renderComponent(<div style={colored}>Hello World!</div>, mountNode);

Dois:

// SASS:
.colored {
  color: $my-color;
}
// HTML:
<div class="colored">Hello World!</div>

O primeiro exemplo usa o que foi descrito na pergunta como: "escrevendo CSS em JavaScript. Não é bonito". O segundo exemplo usa Sass. Embora eu concorde que o uso do JavaScript para escrever CSS pode não ser bonito (para algumas definições de "bonito"), mas há uma vantagem em fazê-lo.

Posso ter variáveis ​​e funções no Sass, mas elas têm escopo lexicamente ou dinamicamente? Eles são estaticamente ou dinamicamente digitados? Forte ou fraca? E os tipos numéricos? Digite coerência? Quais valores são verdadeiros e quais são falsos? Posso ter funções de ordem superior? Recursão? Chamadas de cauda? Fechamentos lexicais? Eles são avaliados em ordem normal ou ordem de aplicação? Existe uma avaliação preguiçosa ou ansiosa? Os argumentos para funções são passados ​​por valor ou por referência? Eles são mutáveis? Imutável? Persistente? E os objetos? Aulas? Protótipos? Herança?

Essas não são perguntas triviais e, no entanto, preciso saber as respostas para entender o código Sass ou Less. Eu já conheço essas respostas para JavaScript, então isso significa que eu já entendo todas as DSLs internas (como os estilos embutidos no React) nesses níveis. Portanto, se eu usar o React, preciso conhecer apenas um conjunto de respostas para essas (e muitas outras semelhantes). ) perguntas, enquanto quando eu uso para, por exemplo. Sass e guidão, então eu tenho que conhecer três conjuntos dessas respostas e entender suas implicações.

Não é para dizer que de um jeito ou de outro é sempre melhor, mas toda vez que você introduz outro idioma no mix, paga um preço que pode não ser tão óbvio à primeira vista, e esse preço é complexo.

Espero ter esclarecido um pouco o que eu originalmente quis dizer.

Ligação de dados

Encadernação bidirecional

Este é um assunto realmente interessante e, de fato, também uma questão de preferência. A mão dupla nem sempre é melhor que a mão única. É uma questão de como você deseja modelar o estado mutável em seu aplicativo. Eu sempre vi as ligações bidirecionais como uma idéia um pouco contrária aos princípios da programação funcional, mas a programação funcional não é o único paradigma que funciona, algumas pessoas preferem esse tipo de comportamento e as duas abordagens parecem funcionar muito bem na prática. Se você estiver interessado nos detalhes das decisões de design relacionadas à modelagem do estado no React, assista à palestra de Pete Hunt (vinculada à pergunta) e à palestra de Tom Occhino e Jordan Walke  que explicam muito bem isso em minha opinião.

Atualização: Veja também outra palestra de Pete Hunt: Seja previsível, não correto: programação DOM funcional .

Atualização 2: Vale a pena notar que muitos desenvolvedores estão argumentando contra o fluxo de dados bidirecional ou ligação bidirecional, alguns até chamam isso de antipadrão. Tomemos, por exemplo, a arquitetura de aplicativos Flux que evita explicitamente o modelo MVC (que provou ser difícil de escalar para grandes aplicativos do Facebook e Instagram) em favor de um fluxo de dados estritamente unidirecional (consulte a conversa sobre Hacker Way: Repensando o Desenvolvimento de Aplicativos Web no Facebook por Tom Occhino, Jing Chen e Pete Hunt para uma boa introdução). Além disso, muitas críticas contra o AngularJS (a estrutura da Web mais popular que é vagamente baseada no modelo MVC, conhecida por ligação de dados bidirecional) inclui argumentos contra esse fluxo de dados bidirecional, consulte:

Atualização 3: Outro artigo interessante que explica bem alguns dos problemas discutidos acima é Desconstruindo o Fluxo do ReactJS - Não usando o MVC com o ReactJS de Mikael Brassman, autor do RefluxJS (uma biblioteca simples para arquitetura de aplicativo de fluxo de dados unidirecional inspirada pelo Flux).

Atualização 4: o Ember.js está atualmente se afastando da ligação de dados bidirecional e, em versões futuras, será unidirecional por padrão. Veja: O Futuro da Ember, por Stefan Penner, do Simpósio Embergarten, em Toronto, em 15 de novembro de 2014.

Atualização 5: Veja também: The Road to Ember 2.0 RFC - discussão interessante na solicitação de recebimento de Tom Dale :

"Quando projetamos a camada de modelo original, descobrimos que fazer todas as ligações de dados bidirecionais não era muito prejudicial: se você não definir uma ligação bidirecional, é de fato uma ligação unidirecional!

Desde então, percebemos (com a ajuda de nossos amigos do React) que os componentes querem poder fornecer dados para seus filhos sem ter que ficar atento a mutações rebeldes.

Além disso, a comunicação entre componentes geralmente é expressa naturalmente como eventos ou retornos de chamada . Isso é possível no Ember, mas o domínio das ligações de dados bidirecionais geralmente leva as pessoas a seguir o caminho de usar as ligações bidirecionais como um canal de comunicação . Desenvolvedores experientes de Ember (geralmente) não cometem esse erro, mas é fácil de cometer ". [Ênfase adicionada]

Nativo x VM

Suporte nativo ao navegador (leia "garantia de ser mais rápido")

Agora, finalmente, algo que não é uma questão de opinião.

Na verdade, aqui é exatamente o contrário. É claro que o código "nativo" pode ser escrito em C ++, mas no que você acha que os mecanismos JavaScript estão escritos?

De fato, os mecanismos JavaScript são realmente incríveis nas otimizações que eles usam hoje - e não apenas no V8, mas também no SpiderMonkey e até no Chakra. E lembre-se de que, com os compiladores JIT, o código não é apenas o mais nativo possível, mas também existem oportunidades de otimização do tempo de execução que são simplesmente impossíveis de serem executadas em qualquer código compilado estaticamente.

Quando as pessoas pensam que o JavaScript é lento, geralmente significam JavaScript que acessa o DOM. O DOM está lento. É nativo, escrito em C ++ e, no entanto, é lento como o inferno por causa da complexidade que precisa implementar.

Abra seu console e escreva:

console.dir(document.createElement('div'));

e veja quantas propriedades um divelemento vazio que nem mesmo está anexado ao DOM deve implementar. Estas são apenas as  propriedades de primeiro nível que são "propriedades próprias", ou seja. não herdado da cadeia de protótipos:

alinhar, aguardar, onvolumechange, ontimeupdate, onsuspend, onsubmit, onstalled, onshow, onselect, onseeking, onseeked, onscroll, onresize, onreset, onratechange, onprogress, onplaying, onplay, onpause, onmousewheel, onmousemovermousemover onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondragluve, ondrenter, ondrag, onbl oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onblur, onabort, spellcheck, isContentEditable, contentEditable, outerText, innerText, accessKey, hidden, webkitdropzone, draggable, tabIndex, dir, translateE, lang, title, child, lang, titlefirstElementChild, children, nextElementSibling, previousElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadow, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, prefixo, namespaceURI, id, estilo, atributos, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastNild, firstChild, firstChild parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, conjunto de dados, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidight, offsetWid, namespaceURI, id, estilo, atributos, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, conjunto de dados, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidight, offsetWid, namespaceURI, id, estilo, atributos, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeName

Muitos deles são realmente objetos aninhados - para ver propriedades de segundo nível (próprias) de um nativo vazio divem seu navegador, consulte este violino .

Quero dizer a sério, a propriedade onvolumechange em cada nó div? Isso é um erro? Não, é apenas uma versão herdada do modelo de evento tradicional DOM Nível 0 de um dos manipuladores de eventos "que deve ser suportada por todos os elementos HTML , como atributos de conteúdo e IDL" [ênfase adicionada] na Seção 6.1.6.2 da especificação HTML por W3C - de jeito nenhum.

Enquanto isso, estas são as propriedades de primeiro nível de um DOM falso divno React:

props, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Quanta diferença, não é? Na verdade, este é o objeto inteiro serializado para JSON ( LIVE DEMO ), porque, na verdade, você pode  serializá-lo para JSON, pois ele não contém nenhuma referência circular - algo impensável no mundo do DOM nativo ( onde seria apenas uma exceção ):

{
  "props": {},
  "_owner": null,
  "_lifeCycleState": "UNMOUNTED",
  "_pendingProps": null,
  "_pendingCallbacks": null,
  "_pendingOwner": null
}

Essa é a principal razão pela qual o React pode ser mais rápido que o DOM do navegador nativo - porque ele não precisa implementar essa bagunça .

Veja esta apresentação de Steven Luscher para ver o que é mais rápido: DOM nativo escrito em C ++ ou um DOM falso escrito inteiramente em JavaScript. É uma apresentação muito justa e divertida.

Atualização: o Ember.js em versões futuras usará um DOM virtual fortemente inspirado no React para melhorar o desempenho. Veja: O Futuro da Ember, por Stefan Penner, do Simpósio Embergarten, em Toronto, em 15 de novembro de 2014.

Para resumir: os recursos dos Componentes da Web, como modelos, ligação de dados ou elementos personalizados, terão muitas vantagens sobre o React, mas até o próprio modelo de objeto de documento ser significativamente simplificado, o desempenho não será um deles.

Atualizar

Dois meses depois de postar essas respostas, houve algumas notícias relevantes aqui. Como acabei de escrever no Twitter , a versão mais recente do editor de texto Atom , escrita pelo GitHub em JavaScript, usa o React do Facebook para obter um melhor desempenho, embora de acordo com a Wikipedia "O Atom seja baseado no Chromium e esteja escrito em C ++", para ter controle total dos a implementação nativa do C ++ DOM (consulte The Nucleus of Atom ) e é garantido que tenha suporte para Web Components, uma vez que é fornecido com seu próprio navegador. É apenas um exemplo muito recente de um projeto do mundo real que poderia ter usado qualquer outro tipo de otimização normalmente indisponível para aplicativos da Web e, no entanto, optou por usar o React, que está escrito em JavaScript, para obter o melhor desempenho, mesmo que o Atom não foi construído com o React, portanto, não foi uma mudança trivial.

Atualização 2

Existe uma comparação interessante de Todd Parker usando o WebPagetest para comparar o desempenho dos exemplos TodoMVC escritos em Angular, Backbone, Ember, Polymer, CanJS, YUI, Knockout, React e Shoestring. Esta é a comparação mais objetiva que eu já vi até agora. O que é significativo aqui é que todos os exemplos respectivos foram escritos por especialistas em todas essas estruturas, estão todos disponíveis no GitHub e podem ser aprimorados por qualquer pessoa que pense que parte do código pode ser otimizado para executar mais rapidamente.

Atualização 3

O Ember.js em versões futuras incluirá vários recursos do React discutidos aqui (incluindo um DOM virtual e uma ligação de dados unidirecional, para citar apenas alguns), o que significa que as idéias originadas no React já estão migrando para outras estruturas. Veja: The Road to Ember 2.0 RFC - discussão interessante na solicitação pull de Tom Dale (Data de início: 2014-12-03): "No Ember 2.0, adotaremos um" DOM ​​virtual "e um modelo de fluxo de dados que abraça o melhores idéias do React e simplifica a comunicação entre os componentes ".

Além disso, o Angular.js 2.0 está implementando muitos dos conceitos discutidos aqui.

Atualização 4

Eu tenho que elaborar algumas questões para responder a este comentário de Igwe Kalu:

"não é sensato comparar o React (JSX ou a saída de compilação) com o JavaScript comum, quando o React acaba por reduzir ao JavaScript comum. [...] Qualquer que seja a estratégia usada pelo React para a inserção do DOM, pode ser aplicada sem o uso do React. Dito isso, ele não adiciona nenhum benefício especial ao considerar o recurso em questão que não seja a conveniência ". (comentário completo aqui )

Caso não tenha ficado claro o suficiente, em parte da minha resposta, estou comparando o desempenho de operar diretamente no DOM nativo (implementado como objetos de host no navegador) versus o DOM falso / virtual do React (implementado em JavaScript). O ponto que eu estava tentando destacar é que o DOM virtual implementado em JavaScript pode superar o DOM real implementado em C ++ e não que o React possa superar o JavaScript (o que obviamente não faria muito sentido, pois está escrito em JavaScript). Meu argumento foi que nem sempre é garantido que o código C ++ "nativo" seja mais rápido que o JavaScript "não nativo". Usar o React para ilustrar esse ponto foi apenas um exemplo.

Mas esse comentário tocou uma questão interessante. Em certo sentido, é verdade que você não precisa de nenhuma estrutura (React, Angular ou jQuery) por qualquer motivo (como desempenho, portabilidade, recursos), porque você sempre pode recriar o que a estrutura faz por você e reinventar a roda - se você pode justificar o custo, é isso.

Mas - como Dave Smith muito bem colocá-lo em Como perder o ponto quando se compara o desempenho framework web : "Ao comparar dois frameworks web, a questão não é possível meu aplicativo ser rápido com o quadro X. A questão é que meu aplicativo ser rápido com o quadro X. "

Na minha resposta de 2011 para: Quais são algumas razões técnicas empíricas para não usar o jQuery , explico um problema semelhante: não é impossível escrever código portátil de manipulação de DOM sem uma biblioteca como o jQuery, mas as pessoas raramente o fazem.

Ao usar linguagens de programação, bibliotecas ou estruturas, as pessoas tendem a usar as maneiras mais convenientes ou idiomáticas de fazer as coisas, não as perfeitas, mas as inconvenientes. O verdadeiro valor de boas estruturas é facilitar o que seria difícil de fazer - e o segredo é tornar as coisas certas convenientes. O resultado ainda tem exatamente o mesmo poder à sua disposição que a forma mais simples de cálculo lambda ou a máquina de Turing mais primitiva, mas a expressividade relativa de certos conceitos significa que esses mesmos conceitos tendem a se expressar com mais facilidade ou facilidade, e que as soluções certas não são apenas possíveis, mas realmente implementadas amplamente.

Atualização 5

Reagir + Desempenho =? O artigo de Paul Lewis, de julho de 2015, mostra um exemplo em que o React é mais lento que o JavaScript baunilha, escrito à mão para uma lista infinita de fotos do Flickr, o que é especialmente significativo no celular. Este exemplo mostra que todos devem sempre testar o desempenho para casos de uso específicos e plataformas e dispositivos de destino específicos.

Agradeço a Kevin Lozandier por chamar minha atenção .


75
é isso que chamo de resposta abrangente, obrigado!
Demwunz

14
Parece que o Atom está se afastando do React. Consulte github.com/atom/atom/issues/3677 .
Juho Vepsäläinen

6
@ash: Se você ler mais adiante, eles falam sobre como gostariam de se afastar completamente do React e de outras estruturas, e apenas rolam por conta própria usando elementos personalizados e o DOM de sombra.
musicfreak

3
Apenas para esclarecer a redação acima, na lista de @ErikAllik, o FRP (Programação Reativa Funcional) não é um novo idioma, mas uma abordagem que está ganhando popularidade. Na verdade, "Elm é baseado na idéia de programação Reactive funcional" (de elm-lang.org), e como ele mencionou, existem estruturas FRP para Haskell, etc.
Jon Coombs

5
tl; leia assim mesmo - resposta brilhante e detalhada!
Mark K Cowan

16

O polímero é incrível. Reagir é incrível. Eles não são a mesma coisa.

O Polymer é uma biblioteca para a construção de componentes da Web compatíveis com versões anteriores.

React é o V no MVC. É a vista, e nada mais. Não por si só, pelo menos.

Reagir não é uma estrutura.

React + Flux + Node + (Gulp ou Grunt) é mais comparável a uma estrutura, mas três dessas coisas não fazem parte da reação.

Existem muitas tecnologias, padrões e estilos de arquitetura que reagem aos desenvolvedores, mas a reação em si não é uma estrutura.

É triste que ninguém tenha tempo para dizer a coisa mais simples possível, que eles não devem ser comparados. Eles têm alguma sobreposição, mas são mais diferentes que o mesmo.

Ambos permitem definir componentes da web, mas de maneiras diferentes. Além disso, são ferramentas muito, muito diferentes.


O React não é o M e o V, e não apenas o V, pois contém e atualiza o estado dos dados e renderiza fragmentos de html por meio de componentes?
abelito 10/04

1
Existem bibliotecas de gerenciamento de estado de reação como flux ou redux, mas elas não são fornecidas com o react.
Robotsushi 11/04

Ah, entendo, não consideramos os dados de exibição como dados de modelo ... até que sejam enviados ao lado do servidor. Mesmo que o React mantenha o estado do componente (exibir dados), ele permanece sendo exibido até o envio. Isso faz sentido.
abelito 11/04

15

O pessoal do React tem uma boa explicação sobre a comparação entre o React e os Web Components:

Tentar comparar e contrastar Reagir com os WebComponents resulta inevitavelmente em conclusões ilusórias, porque as duas bibliotecas são construídas para resolver problemas diferentes. Os WebComponents fornecem um forte encapsulamento para componentes reutilizáveis, enquanto o React fornece uma biblioteca declarativa que mantém o DOM sincronizado com seus dados. Os dois objetivos são complementares; os engenheiros podem combinar e combinar as tecnologias. Como desenvolvedor, você é livre para usar o React em seus WebComponents, ou para usar WebComponents no React, ou ambos.


14

Outra resposta em um ponto especificamente:

Escreva JavaScript em baunilha JavaScript, escreva CSS em CSS, escreva HTML em HTML.

Nada impede que você escreva Javascript, por exemplo, CoffeeScript, TypeScript, ClojureScript ou qualquer outra coisa. É apenas uma questão de preferência.

HTML é o melhor DSL para documentos HTML estáticos . Mas isso não fornece nada para HTML dinâmico. E no navegador, a melhor linguagem para tornar o HTML dinâmico é o Javascript, não o HTML puro com manipulação DOM ad-hoc do Javascript ou linguagem de modelo como o Handlebars, que nem sequer são meias línguas.

Para CSS, se seu CSS é estático, você o escreve como de costume. Se precisar ser dinâmico com base em alguns valores de tempo de execução, é a mesma história do HTML: o Javascript é a melhor maneira de torná-lo dinâmico.


1
Agradeço a resposta, mas esse não foi o meu ponto. Espero que minhas edições tenham tornado a pergunta um pouco mais clara.
precisa saber é o seguinte

1
Desculpe, não. Você ainda pode escrever seu estilo em um idioma de qualquer estilo em um arquivo separado. E o JSX do React faz parecer que você está usando uma linguagem de marcação.
precisa saber é o seguinte

3
"Javascript é a melhor maneira de tornar [CSS] dinâmico" - simplesmente dizendo que na verdade não explica o porquê.
Pilau

1
Bem, se os estilos / classes precisarem mudar de acordo com a entrada do usuário ou com as regras de negócios, basta usar o javascript para alterá-los. No vanilla js, você manipularia as propriedades classList ou styles de um nó DOM. Com o React, você pode atingir o mesmo objetivo de manipular o DOM Virtual. Está mais claro?
DjebbZ

2
Vjeux, principal colaborador do React, recentemente deu uma palestra em que aborda o conceito "CSS em JS" usando o React. Eu acho que é interessante, você pode querer ver do que se trata: blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ

6

Não usei Web Components, mas parece que eles exigem que você adicione lógica de mutação codificada manualmente aos manipuladores de eventos.

snippet do exemplo do Polymer:

 <script>
   Polymer({
     counterChanged: function() {
       this.$.counterVal.classList.add('highlight');
     },
 ...

O objetivo principal do React é reduzir a complexidade, eliminando a lógica de mutação. Em vez disso, você regenera ingenuamente um DOM virtual e permite que o algoritmo diff do React descubra o que precisa ser alterado no DOM real.


5
Não tenho certeza de onde você conseguiu esse exemplo, mas o Polymer também desencoraja a mutação DOM manual em favor da ligação de dados, inclusive para nomes de classe .
CletusW

É o exemplo da guia "criar elementos" na primeira página de polymer-project.org .
limscoder

4
Uau, você está certo! Eu acho que eles queriam apenas um exemplo de localização automática de nós. Isso provavelmente não é o melhor para dar, no entanto.
CletusW

6

Acho que a maior desvantagem do React, na minha opinião, é que ele não se baseia nos padrões da web. O React é uma ferramenta muito poderosa no momento, mas como contorna muito do que o navegador fornece sempre que possível, as decisões que pareciam fazer sentido agora provavelmente não farão sentido daqui a alguns anos, pois as instalações internas do navegador continuam a melhorar. Então, eu gostaria de falar sobre isso e como isso afeta alguns aspectos diferentes dos aplicativos da web.

atuação

As pessoas gostam de argumentar que a vantagem do React é que ele reinventa completamente todo o DOM e modelo de evento, e o DOM padrão existente é pesado e caro e não é, mas no final do dia eu não encontrei o desempenho do DOM. Reagir para ser melhor do que o que posso obter de um aplicativo de backbone ou polímero bem escrito. De fato, na maior parte da minha experiência profissional, o desempenho do React foi realmente um pouco pior. Isso não quer dizer que o React seja lento ... Não é apenas a opção de desempenho mais avançada que todos pensávamos antes de colocar nossas mãos nele.

Na resposta da rsp, ele aponta que o modelo DOM do React para uma div é muito mais leve que o div nat do DOM, e isso certamente é verdade. No entanto, para que o React seja útil, essa div 'virtual' deve acabar se tornando uma div real em algum momento. Portanto, na minha visão de mundo, não se trata de uma divisão React versus uma divisão nativa. É uma div React + uma div nativa vs apenas uma div nativa. A sobrecarga da versão do DOM do React não é trivial e, se os padrões abandonarem alguns desses atributos desnecessários e permitirem que os nós DOM nativos sejam muito mais leves, subitamente essa sobrecarga parecerá realmente cara.

Em um dos meus locais de trabalho anteriores, tivemos alguns aplicativos no Polymer e outros no React. Uma das primeiras aplicações do Polymer acabou sendo reescrita no React, porque era o que a empresa usava de padrão e, com base nas medições que fiz na versão React desse mesmo aplicativo, acabamos usando cerca de 30% mais memória do que a versão do Polymer , e embora a diferença seja marginal, a versão Polymer foi renderizada em menos tempo também. Uma coisa a considerar aqui é que estamos falando de aplicativos escritos por pessoas, e as pessoas não são perfeitas, portanto, é possível que a implementação do React desse aplicativo não esteja tirando vantagem de tudo o que o React é capaz. Mas acho que pelo menos parte disso tem a ver com a sobrecarga do React por ter sua própria versão do DOM.

O React reinventa todo o DOM usando seu próprio modelo e o usa para uma grande otimização de desempenho. Uma exibição é renderizada em um DOM virtual e projetada no DOM real. Quando há uma alteração e a visualização deve ser atualizada, a visualização é novamente renderizada novamente em um DOM virtual e essa árvore é diferente da árvore anterior para determinar quais nós devem ser alterados no DOM real para refletir essa alteração. na vista. Embora essa seja uma abordagem muito inteligente para fazer atualizações eficientes do DOM, existe uma sobrecarga para manter todas essas árvores virtuais do DOM e diferenciá-las para determinar o que alterar no DOM real. No momento, essa sobrecarga é bastante compensada pelos benefícios de desempenho, mas à medida que o DOM nativo é aprimorado ao longo do tempo, a escala muda na outra direção. Preocupo-me com a idade dos aplicativos React, e se daqui a três anos eles forem muito mais lentos do que as coisas que lidam com o DOM mais diretamente. Essa abordagem virtual do DOM é um pouco difícil, e outras bibliotecas como a Polymer foram capazes de implementar abordagens muito eficientes para lidar com o DOM de uma maneira muito mais sutil.

Atualização para desempenho: uma das bibliotecas que encontrei há algum tempo faz o que eu acho que é um trabalho melhor para gerenciar atualizações no DOM. É a biblioteca Dom Incremental do Google, e acho que o fato de funcionar com o dom no local e não precisar criar uma 'cópia virtual' é uma abordagem muito mais limpa, com muito menos sobrecarga de memória. Veja mais aqui: http://google.github.io/incremental-dom/#about

Componentes declarativos vs imperativos

Uma das coisas que você sempre ouve quando se fala em componentes do seu aplicativo é todos os benefícios de seus componentes serem declarativos. Dentro da visão de mundo do React, tudo é legal e declarativo. Você escreve JavaScript que retorna a marcação e o React cola tudo junto para você. E isso é ótimo se você estiver lidando com um aplicativo totalmente novo que usa apenas o React e nada mais. Você pode escrever algum componente e, desde que esteja dentro de uma parte do DOM do React, é tão simples quanto colocar essa tag na página para consumir seu componente.

Mas assim que você pega esses componentes e os usa fora do React, as coisas ficam muito mais confusas. Como a maneira como os componentes do React são transformados em tags está completamente fora do que os padrões da web fornecem, nada além do React sabe como fornecer uma maneira declarativa de consumir esses componentes. Se eu quiser colocar os componentes React em uma exibição Backbone existente que esteja usando modelos de guidão, você precisará renderizar uma div fictícia em seu modelo com uma classe ou ID que possa ser usada como alça e, em seguida, escreva JavaScript imperativo para encontrar essa div fictícia e montar seu componente nele. Tem um aplicativo Express.js que usa modelos do lado do servidor? Bem, é a mesma música e dança. Uma página JSP? Você ri, mas ainda existem muitos aplicativos para usá-los. A menos que você seja algum tipo de inicialização sem código existente, você você precisará escrever um encanamento para reutilizar os componentes do React em muitos aplicativos. Enquanto isso, o Polymer alcança componentes através do padrão Web Components e, usando a especificação de elemento personalizado, o Polymer pode criar componentes que o navegador apenas sabe consumir de forma nativa. Eu posso colocar um componente Polymer em uma página JSP, um modelo Express.js, uma exibição ASP.NET, uma exibição Backbone ... mesmo dentro de um componente React. Literalmente, em qualquer lugar que você possa usar HTML, poderá consumir um componente Polymer. As pessoas que estão planejando reutilizar estão buscando os padrões da Web, porque os padrões são os contratos que facilitam a compatibilidade entre as coisas. O YouTube continua criando cada vez mais coisas no Polymer (fonte: O Polymer alcança componentes através do padrão Web Components e, usando a especificação Custom Element, o Polymer pode criar componentes que o navegador apenas sabe como consumir. Eu posso colocar um componente Polymer em uma página JSP, um modelo Express.js, uma exibição ASP.NET, uma exibição Backbone ... mesmo dentro de um componente React. Literalmente, em qualquer lugar que você possa usar HTML, poderá consumir um componente Polymer. As pessoas que estão planejando reutilizar estão buscando os padrões da Web, porque os padrões são os contratos que facilitam a compatibilidade entre as coisas. O YouTube continua criando cada vez mais coisas no Polymer (fonte: O Polymer alcança componentes através do padrão Web Components e, usando a especificação Custom Element, o Polymer pode criar componentes que o navegador apenas sabe como consumir. Eu posso colocar um componente Polymer em uma página JSP, um modelo Express.js, uma exibição ASP.NET, uma exibição Backbone ... mesmo dentro de um componente React. Literalmente, em qualquer lugar que você possa usar HTML, poderá consumir um componente Polymer. As pessoas que estão planejando reutilizar estão buscando os padrões da Web, porque os padrões são os contratos que facilitam a compatibilidade entre as coisas. O YouTube continua criando cada vez mais coisas no Polymer (fonte: Eu posso colocar um componente Polymer em uma página JSP, um modelo Express.js, uma exibição ASP.NET, uma exibição Backbone ... mesmo dentro de um componente React. Literalmente, em qualquer lugar que você possa usar HTML, poderá consumir um componente Polymer. As pessoas que estão planejando reutilizar estão buscando os padrões da Web, porque os padrões são os contratos que facilitam a compatibilidade entre as coisas. O YouTube continua criando cada vez mais coisas no Polymer (fonte: Eu posso colocar um componente Polymer em uma página JSP, um modelo Express.js, uma exibição ASP.NET, uma exibição Backbone ... mesmo dentro de um componente React. Literalmente, em qualquer lugar que você possa usar HTML, poderá consumir um componente Polymer. As pessoas que estão planejando reutilizar estão buscando os padrões da Web, porque os padrões são os contratos que facilitam a compatibilidade entre as coisas. O YouTube continua criando cada vez mais coisas no Polymer (fonte:http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer ), e eu posso apenas imaginar que o aspecto baseado em padrões do Polymer é a razão disso. O player do YouTube no meio da página do YouTube pode ser transformado em um componente que inclua uma fonte de conteúdo como uma propriedade e, de repente, qualquer pessoa que queira incorporar o player do YouTube em sua página pode literalmente usar exatamente o mesmo código de player que o YouTube está usando , e eles podem fazer isso simplesmente colocando uma tag na página deles.

Sumário

Eu posso ver que definitivamente existem alguns aspectos atraentes do React agora. Se tudo o que você está usando é React, é possível criar alguns widgets e alguns componentes e reutilizá-los declarativamente em todo o lugar. Mas acho que o React teria sido muito melhor se tivesse usado alguns dos padrões de componentes da Web para conseguir o que faz, em vez de criar um navegador dentro de um navegador e um mecanismo complexo para manter tudo sincronizado.

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.