Por que o JavaScript devora HTML: exemplos de código

O desenvolvimento da Web está em constante evolução. Recentemente, uma tendência se tornou popular, o que basicamente contradiz a idéia geralmente aceita de como desenvolver aplicativos da web. Alguns têm grandes esperanças para ele, enquanto outros estão decepcionados. Cada um tem suas próprias razões para isso, o que, em poucas palavras, é difícil de explicar.



O código da página da Web tradicionalmente consiste em três seções, cada uma das quais cumprindo suas obrigações: o código HTML define a estrutura e a semântica, o código CSS determina a aparência e o código JavaScript determina seu comportamento. Em equipes que envolvem designers, desenvolvedores de HTML / CSS e desenvolvedores de JavaScript, essa separação é natural: os designers definem elementos visuais e uma interface com o usuário, os desenvolvedores de HTML e CSS colocam esses elementos visuais em uma página do navegador, e os desenvolvedores de JavaScript adicionam interação do usuário. amarre tudo e "faça funcionar". Todos podem trabalhar em suas tarefas sem interferir no código das outras duas categorias de desenvolvedores. Mas tudo isso é verdade para o chamado "estilo antigo".

Nos últimos anos, os desenvolvedores de JavaScript começaram a determinar a estrutura da página em JavaScript, e não em HTML (por exemplo, usando a estrutura React js ), o que ajuda a simplificar a criação e manutenção do código de interação do usuário. Sem estruturas js, o desenvolvimento de sites modernos é muito mais difícil. Obviamente, quando você diz a alguém que o código HTML escrito por ele precisa ser dividido em pedaços e misturado ao JavaScript, com o qual ele está muito familiarizado, isso (por razões óbvias) pode ser percebido com hostilidade. No mínimo, o interlocutor perguntará por que precisamos disso e como nos beneficiaremos disso.

Como desenvolvedor de JavaScript em uma equipe multifuncional, essa pergunta às vezes é feita para mim e, muitas vezes, é difícil para mim responder. Todos os materiais que encontrei neste tópico foram escritos para um público que já conhece o JavaScript. E isso não é muito bom para quem se especializa exclusivamente em HTML e CSS. Mas é provável que o padrão HTML-in-JS (ou qualquer outra coisa que ofereça os mesmos benefícios) seja demandado por algum tempo, então acho que isso é uma coisa importante que todos os envolvidos no desenvolvimento da web devem entender.

Neste artigo, darei exemplos de código para aqueles que estão interessados, mas meu objetivo é explicar essa abordagem para que ela possa ser entendida sem eles.

Likbez: HTML, CSS e JavaScript


Para maximizar o público deste artigo, quero falar brevemente sobre o papel que essas linguagens desempenham na criação de páginas da Web e que tipo de separação entre elas existia inicialmente. Se todos sabem disso, podem pular esta seção.

HTML: para estrutura e semântica


O código HTML (HyperText Markup Language) define a estrutura e a semântica do conteúdo que será colocado na página. Por exemplo, o código HTML deste artigo contém o texto que você está lendo agora e, de acordo com a estrutura especificada, esse texto é colocado em um parágrafo separado, após o cabeçalho e antes de colar o CodePen .

Por exemplo, crie uma página da web simples com uma lista de compras:



Podemos salvar esse código em um arquivo, abri-lo em um navegador da Web e o navegador exibirá o resultado. Como você pode ver, o código HTML neste exemplo é uma página que contém o cabeçalho "Lista de compras" (itens de compras (2 itens)), uma caixa de texto de entrada, um botão "Adicionar item" e uma lista de dois itens ("Ovos" e "Petróleo"). O usuário digitará o endereço em seu navegador da Web e, em seguida, o navegador solicitará esse código HTML do servidor, fará o download e exibirá. Se já houver elementos na lista, o servidor poderá enviar HTML com elementos prontos, como neste exemplo.

Tente digitar algo no campo de entrada e clique no botão "Adicionar item". Você verá que nada está acontecendo. O botão não está associado a nenhum código que possa alterar o HTML, e o HTML não pode alterar nada por si só. Voltaremos a isso em um minuto.

CSS: para mudar a aparência


O código CSS (Cascading Style Sheets) define a aparência da página. Por exemplo, o CSS deste artigo define a fonte, o espaçamento e a cor do texto que você está lendo.

Você deve ter notado que nosso exemplo de lista de compras parece muito simples. O HTML não permite que itens como espaçamento, tamanhos de fonte e cores sejam especificados. É por isso que usamos CSS. Poderíamos adicionar um código CSS para esta página para decorar um pouco:



Como você pode ver, esse código CSS alterou o tamanho e a espessura dos caracteres de texto, bem como a cor do plano de fundo. Um desenvolvedor pode, por analogia, escrever regras para seu próprio estilo, e elas serão aplicadas seqüencialmente a qualquer estrutura HTML: se adicionarmos elementos de seção, botão ou ul a esta página , as mesmas alterações de fonte serão aplicadas.
Mas o botão Adicionar item ainda não faz nada: aqui só precisamos de JavaScript.

JavaScript: para implementar o comportamento


O código JavaScript define o comportamento de elementos interativos ou dinâmicos em uma página. Por exemplo, o CodePen é escrito usando JavaScript.

Para que o botão Adicionar item em nosso exemplo funcione sem JavaScript, precisaríamos usar código HTML especial para forçá-lo a enviar dados de volta ao servidor ( <form action \ u003d '...'> se você estiver subitamente interessado). Além disso, o navegador recarregará a versão atualizada de todo o arquivo HTML sem salvar o estado atual da página. Se essa lista de compras fizesse parte de uma grande página da Web, tudo o que o usuário fizesse seria perdido. Não importa quantos pixels você moveu para baixo ao ler o texto - quando você reiniciar o servidor, você retornará ao início, não importa quantos minutos do vídeo você assistiu - quando você reiniciar, ele começará novamente.

É assim que todos os aplicativos da Web costumavam funcionar: toda vez que um usuário interagia com uma página da Web, ele parecia fechar o navegador e abri-lo novamente. Isso não importa muito para um estudo de caso simples, mas para uma página grande e complexa, que pode levar algum tempo para carregar, essa abordagem não é eficaz para o navegador ou o servidor.

Se quisermos alterar algo na página sem recarregar completamente essa página, precisamos usar JavaScript:



Agora, quando digitar o texto no campo de entrada e clicar no botão Adicionar Item, nosso novo elemento será adicionado à lista e o número de elementos na parte superior será atualizado! Em um aplicativo real, também adicionaríamos algum código para enviar um novo item para o servidor em segundo plano, para que ele apareça na próxima vez que a página for carregada.

A separação de JavaScript de HTML e CSS é justificada mesmo neste exemplo simples. Interações mais complexas funcionam assim: o HTML é carregado e exibido, e o JavaScript é iniciado posteriormente para adicionar algo a ele e alterá-lo. No entanto, à medida que a complexidade do aplicativo Web aumenta, precisamos monitorar cuidadosamente o que, onde e quando nosso código JavaScript é alterado.

Se continuarmos desenvolvendo esse aplicativo com uma lista de compras, podemos adicionar botões para editar ou remover itens da lista. Suponha que escrevamos código JavaScript para um botão que exclua um elemento, mas esqueça de adicionar um código que atualize informações sobre o número total de elementos na parte superior da página. De repente, recebemos um erro: depois que o usuário exclui o item, o número total indicado na página não corresponde à lista!

Assim que percebemos o erro, o corrigimos adicionando a mesma linha totalText.innerHTML do nosso código para Adicionar item ao código para Remover item. Agora, temos o mesmo código, duplicado em vários lugares. Mais tarde, digamos, queremos alterar esse código para que, em vez de "(2 itens)" na parte superior da página, exiba "Itens: 2". Devemos garantir que não esquecemos de atualizar esse código nos três locais: em HTML, no código JavaScript do botão Add Item e no código JavaScript do botão Remove Item. Caso contrário, teremos outro erro, devido ao qual este texto será alterado drasticamente após a interação com o usuário.

Já neste exemplo simples, vemos como é fácil ficar confuso no código. Claro. Existem abordagens e práticas para otimizar o código JavaScript e facilitar a solução desse problema. No entanto, à medida que as coisas se tornam mais complicadas, teremos que continuar a reestruturar e reescrever constantemente o projeto para que ele possa ser facilmente desenvolvido e mantido. Enquanto HTML e JavaScript são armazenados separadamente, pode ser necessário muito esforço para garantir a sincronização entre os dois. Essa é uma das razões pelas quais novas estruturas JavaScript, como o React, se tornaram populares: elas foram projetadas para fornecer um relacionamento mais formalizado e eficiente entre HTML e JavaScript. Para entender como isso funciona, primeiro precisamos nos aprofundar um pouco mais na ciência da computação.

Programação imperativa versus declarativa


A principal coisa a entender é a diferença de pensamento. A maioria das linguagens de programação permite seguir apenas um paradigma, embora algumas delas suportem duas de uma vez. É importante entender os dois paradigmas para apreciar a principal vantagem do HTML-JS, do ponto de vista do desenvolvedor JavaScript.

  • . «» , . ( ) : , , . , , . - «». Vanilla JavaScript , jQuery. JavaScript .
    • « X, Y, Z».
    • : , .selected; , .selected.

  • . , . , , «» (), , - . , . (, React), , , . , , , , . , :
    • « XYZ. , , .
    • Exemplo: este elemento possui uma classe .selected se o usuário o selecionou.


HTML é uma linguagem declarativa


Esqueça o JavaScript por um momento. Aqui está um fato importante: HTML é uma linguagem declarativa. No arquivo HTML, você pode declarar algo como:

<section>
  <h1>Hello</h1>
  <p>My name is Mike.</p>
</section>

Quando o navegador lê este código HTML, ele determina independentemente as etapas necessárias e as executa:

  1. Crie um elemento de seção .
  2. Crie um elemento de cabeçalho de nível 1 ( h1 ).
  3. Defina o texto do elemento de título como "Hello".
  4. Coloque o elemento title no elemento section.
  5. Crie um elemento de parágrafo ( p ).
  6. Defina o texto do elemento do parágrafo como "Meu nome é Mike".
  7. Coloque um elemento de parágrafo em um elemento de seção .
  8. Coloque o elemento de seção em um documento HTML.
  9. Exiba o documento na tela.

Para um desenvolvedor web, exatamente como o navegador faz essas coisas não importa: tudo o que importa é o que elas fazem. Este é um ótimo exemplo para ilustrar a diferença entre os dois paradigmas de programação. Em resumo, o HTML é uma abstração declarativa envolvida em um mecanismo de renderização de navegador da Web implementado de forma imperiosa. Ele se preocupa com como, então você só precisa se preocupar com o que. Você pode aproveitar a vida enquanto escreve HTML declarativo, porque as pessoas boas da Mozilla, Google e Apple escreveram um código imperativo para você quando criaram seu navegador da web.

JavaScript é uma linguagem imperativa


Já vimos um exemplo simples de JavaScript imperativo no exemplo da lista de compras acima e descrevi como a complexidade das funções do aplicativo afeta o esforço necessário para implementá-las e a probabilidade de erros nessa implementação.

Agora, vamos examinar uma tarefa um pouco mais complexa e ver como ela pode ser simplificada usando uma abordagem declarativa. Imagine uma página da web que contenha o seguinte:

  • uma lista de sinalizadores sinalizados, cada linha que muda de cor quando selecionada;
  • texto abaixo, por exemplo, “1 de 4 selecionados”, que deve ser atualizado quando os sinalizadores forem alterados;
  • Botão Selecionar tudo, que deve ser desativado se todas as caixas de seleção já estiverem marcadas;
  • Botão Selecionar nenhum, que deve ser desativado se as caixas de seleção não estiverem selecionadas.

Aqui está uma implementação em HTML, CSS e JavaScript imperativo:



const captionText = document.getElementById('caption-text');
const checkAllButton = document.getElementById('check-all-button');
const uncheckAllButton = document.getElementById('uncheck-all-button');
const checkboxes = document.querySelectorAll('input[type="checkbox"]');

function updateSummary() {
  let numChecked = 0;
  checkboxes.forEach(function(checkbox) {
    if (checkbox.checked) {
      numChecked++;
    }
  });
  captionText.innerHTML = `${numChecked} of ${checkboxes.length} checked`;
  if (numChecked === 0) {
    checkAllButton.disabled = false;
    uncheckAllButton.disabled = true;
  } else {
    uncheckAllButton.disabled = false;
  }
  if (numChecked === checkboxes.length) {
    checkAllButton.disabled = true;
  }
}

checkAllButton.addEventListener('click', function() {
  checkboxes.forEach(function(checkbox) {
    checkbox.checked = true;
    checkbox.closest('tr').className = 'checked';
  });
  updateSummary();
});

uncheckAllButton.addEventListener('click', function() {
  checkboxes.forEach(function(checkbox) {
    checkbox.checked = false;
    checkbox.closest('tr').className = '';
  });
  updateSummary();
});

checkboxes.forEach(function(checkbox) {
  checkbox.addEventListener('change', function(event) {
    checkbox.closest('tr').className = checkbox.checked ? 'checked' : '';
    updateSummary();
  });
});

Dor de cabeça como ela é


Para implementar esta função usando JavaScript imperativo, precisamos fornecer ao navegador algumas instruções detalhadas. Esta é uma descrição verbal do código do exemplo acima.
Em nosso HTML, declaramos a estrutura da página original:
  • Existem quatro elementos de linha (uma linha de uma tabela, é uma lista), cada um dos quais contém um sinalizador. A terceira bandeira está marcada.
  • Há um texto "1 de 4 selecionado".
  • Há um botão Selecionar tudo que está ativado.
  • Há um botão Selecionar nenhum, que está desativado.

Em nosso JavaScript, escrevemos instruções sobre o que precisa ser alterado quando cada um desses eventos acontece:
Quando um sinalizador muda de não marcado para marcado:
  • Localize a linha que contém a caixa de seleção e adicione a classe CSS selecionada.
  • Encontre todos os sinalizadores na lista e calcule quantos deles estão marcados e quantos não estão.
  • Encontre o texto e atualize-o, indicando o número correto de compras selecionadas e o número total.
  • Encontre o botão Selecionar nenhum e ative-o se estiver desabilitado.
  • Se todas as caixas de seleção estiverem marcadas, localize o botão Selecionar tudo e desative-o.

Quando um sinalizador muda de marcado para não marcado:
  • Localize a linha que contém o sinalizador e remova a classe .selected dele.
  • Encontre todas as caixas de seleção na lista e calcule quantas delas estão marcadas e quantas não.
  • Encontre o item de texto do resumo e atualize-o com o número e o total verificados.
  • Encontre o botão Selecionar tudo e ative-o se estiver desabilitado.
  • Se todas as caixas estiverem desmarcadas, localize o botão Selecionar nenhum e desative-o.

Quando o botão Selecionar tudo é pressionado:
  • Encontre todas as caixas de seleção na lista e marque-as.
  • Localize todas as linhas da lista e adicione a classe .selected a elas.
  • Encontre o texto e atualize-o.
  • Encontre o botão Selecionar tudo e desligue-o.
  • Encontre o botão Selecionar nenhum e ative-o.

Quando o botão Selecionar nenhum é pressionado:
  • Encontre todas as caixas de seleção na lista e limpe todas as caixas de seleção.
  • Encontre todas as linhas da lista e remova a classe .selected delas.
  • Encontre o elemento de texto do currículo e atualize-o.
  • Encontre o botão Selecionar tudo e ligue-o.
  • Encontre o botão Selecionar nenhum e desligue-o.

Uau ... Isso é muito, certo? Bem, é melhor não esquecermos de escrever código para todas as situações possíveis. Se esquecermos ou estragar alguma dessas instruções, ocorreremos um erro: os totais não correspondem às caixas de seleção, ou o botão que não faz nada quando você clica nela ou a linha selecionada fica com a cor errada ou algo assim, está ativada ainda, sobre o qual não pensamos e não saberemos até que o usuário se queixe.

Temos realmente um grande problema aqui: não existe uma entidade que contenha informações completas sobre o estadodo nosso aplicativo (neste caso, esta é a resposta para a pergunta “quais sinalizadores estão marcados?”) e seria responsável por atualizar essas informações. Os sinalizadores, é claro, sabem se estão marcados, mas o código CSS para as linhas da tabela, texto e cada botão também deve estar ciente disso. Cinco cópias dessas informações são armazenadas separadamente em todo o HTML e, quando elas são alteradas em qualquer um desses locais, o desenvolvedor do JavaScript deve capturar isso e escrever um código imperativo para sincronizar com as alterações em outros locais.

E este ainda é um exemplo simples de um pequeno componente de página. Mesmo que esse conjunto de instruções pareça uma dor de cabeça, imagine quão complexa e frágil um aplicativo da Web maior se torna quando você precisa implementar tudo isso em JavaScript obrigatório. Para muitas aplicações web complexas e modernas, essa solução não é dimensionada da palavra "completamente".

Estamos procurando a fonte da verdade


Ferramentas como o React permitem o uso declarativo do JavaScript. Assim como o HTML é uma abstração declarativa sobre as instruções para exibição em um navegador da Web, o React é uma abstração declarativa sobre JavaScript.

Lembre-se de como o HTML nos permite focar na estrutura da página e não nos detalhes da implementação, e como o navegador exibe essa estrutura? Da mesma forma, quando usamos o React, podemos nos concentrar na estrutura, definindo-a com base nos dados armazenados em um único local. Esse processo é chamado de ligação unidirecional e o local dos dados do estado do aplicativo é chamado de "fonte única da verdade". Quando a fonte da verdade muda, o React atualiza automaticamente a estrutura da página para nós. Ele cuidará das etapas necessárias nos bastidores, como faz um navegador da Web para HTML. Embora o React seja usado como exemplo aqui, essa abordagem também funciona para outras estruturas, como o Vue.

Vamos voltar à nossa lista de caixas de seleção do exemplo acima. Nesse caso, a “verdade” que queremos saber é bastante concisa: quais sinalizadores são verificados? Outros detalhes (por exemplo, texto, cor das linhas, quais botões estão ativados) já são informações obtidas com base na fonte da verdade. E por que eles deveriam ter sua própria cópia dessas informações? Eles devem simplesmente usar uma única fonte de verdade somente leitura, e todos os elementos da página devem "saber" quais caixas de seleção estão marcadas e se comportam de acordo. Você pode dizer que as linhas da tabela, o texto e os botões devem poder responder automaticamente a uma caixa de seleção, dependendo de ela estar marcada ou não ("veja o que está acontecendo lá?")

Diga-me o que você quer (o que você realmente quer)


Para implementar esta página com o React, podemos substituir a lista por algumas descrições de fatos simples:

  • Há uma lista de valores verdadeiros / falsos chamados checkboxValues ​​que mostra quais campos estão marcados.
    • Exemplo: checkboxValues ​​\ u003d [falso, falso, verdadeiro, falso]
    • Esta lista mostra que temos quatro sinalizadores, apenas o terceiro está definido.

  • Para cada valor em checkboxValues ​​na tabela, há uma linha que:
    • tem uma classe CSS chamada .selected se o valor for verdadeiro e
    • contém um sinalizador que é verificado se o valor é verdadeiro.

  • Há um elemento de texto que contém o texto "{x} de {y} selecionado", em que {x} é o número de valores verdadeiros em checkboxValues ​​e {y} é o número total de valores em checkboxValues.
  • Existe um botão Selecionar tudo que está ativado se checkboxValues ​​tiver valores falsos.
  • Select None, , checkboxValues ​​ true.
  • , checkboxValues.
  • Select All , checkboxValues ​​ true.
  • Select None checkboxValues ​​ false.

Você notará que os três últimos parágrafos ainda são instruções imperativas (“quando isso acontecer, faça”), mas esse é o único código imperativo que precisamos escrever. Essas são três linhas de código e todas atualizam uma única fonte de verdade.

O restante são declarações declarativas ("existe ..."), que agora são construídas diretamente na definição da estrutura da página. Para fazer isso, escrevemos código para nossos elementos usando uma extensão de sintaxe JavaScript especial - XML ​​XML (JSX). É semelhante ao HTML: o JSX permite que você use a sintaxe semelhante ao HTML para descrever a estrutura da interface, bem como o JavaScript comum. Isso nos permite misturar a lógica JS com a estrutura HTML, para que a estrutura possa ser diferente a qualquer momento. Tudo depende do conteúdo de checkboxValues.

Reescrevemos nosso exemplo no React:



function ChecklistTable({ columns, rows, initialValues, ...otherProps }) {
  const [checkboxValues, setCheckboxValues] = React.useState(initialValues);
  
  function checkAllBoxes() {
    setCheckboxValues(new Array(rows.length).fill(true));
  }
  
  function uncheckAllBoxes() {
    setCheckboxValues(new Array(rows.length).fill(false));
  }
  
  function setCheckboxValue(rowIndex, checked) {
    const newValues = checkboxValues.slice();
    newValues[rowIndex] = checked;
    setCheckboxValues(newValues);
  }
  
  const numItems = checkboxValues.length;
  const numChecked = checkboxValues.filter(Boolean).length;
  
  return (
    <table className="pf-c-table pf-m-grid-lg" role="grid" {...otherProps}>
      <caption>
        <span>{numChecked} of {numItems} items checked</span>
        <button
          onClick={checkAllBoxes}
          disabled={numChecked === numItems}
          className="pf-c-button pf-m-primary"
          type="button"
        >
          Check all
        </button>
        <button
          onClick={uncheckAllBoxes}
          disabled={numChecked === 0}
          className="pf-c-button pf-m-secondary"
          type="button"
        >
          Uncheck all
        </button>
      </caption>
      <thead>
        <tr>
          <td />
          {columns.map(function(column) {
            return <th scope="col" key={column}>{column}</th>;
          })}
        </tr>
      </thead>
      <tbody>
        {rows.map(function(row, rowIndex) {
          const [firstCell, ...otherCells] = row;
          const labelId = `item-${rowIndex}-${firstCell}`;
          const isChecked = checkboxValues[rowIndex];
          return (
            <tr key={firstCell} className={isChecked ? 'checked' : ''}>
              <td className="pf-c-table__check">
                <input
                  type="checkbox"
                  name={firstCell}
                  aria-labelledby={labelId}
                  checked={isChecked}
                  onChange={function(event) {
                    setCheckboxValue(rowIndex, event.target.checked);
                  }}
                />
              </td>
              <th data-label={columns[0]}>
                <div id={labelId}>{firstCell}</div>
              </th>
              {otherCells.map(function(cell, cellIndex) {
                return (
                  <td key={cell} data-label={columns[1 + cellIndex]}>
                    {cell}
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
};

function ShoppingList() {
  return (
    <ChecklistTable
      aria-label="Shopping list"
      columns={['Item', 'Quantity']}
      rows={[
        ['Sugar', '1 cup'],
        ['Butter', '½ cup'],
        ['Eggs', '2'],
        ['Milk', '½ cup'],
      ]}
      initialValues={[false, false, true, false]}
    />
  );
}

ReactDOM.render(
  <ShoppingList />,
  document.getElementById('shopping-list')
);


JSX parece peculiar. Quando eu encontrei isso pela primeira vez, parecia-me que era simplesmente impossível fazê-lo. Minha reação inicial foi: “O quê? O HTML não pode estar dentro do código JavaScript! ” E eu não era o único. No entanto, isso não é HTML, mas o JavaScript é usado como HTML. De fato, esta é uma solução poderosa.

Lembra das 20 instruções imperativas acima? Agora nós temos três deles. O restante das instruções imperativas (internas) que o React executa por nós nos bastidores - toda vez que a caixa de seleçãoValues ​​muda.

Com esse código, uma situação não pode mais ocorrer quando o texto ou a cor da linha não corresponder às caixas de seleção ou quando o botão estiver ativado, embora deva ser desativado. Há toda uma categoria de erros que agora simplesmente não podem ocorrer em nosso aplicativo da web. Todo o trabalho é feito com base em uma única fonte de verdade, e nós desenvolvedores podemos escrever menos código e dormir melhor à noite. Bem, desenvolvedores JavaScript, pelo menos ...

JavaScript derrotado em JavaScript: faminto


À medida que os aplicativos da Web se tornam mais complexos, a manutenção da separação clássica de tarefas entre HTML e JavaScript se torna mais dolorosa. O HTML foi originalmente projetado para páginas da Web estáticas. Para adicionar funções interativas mais complexas, é necessário implementar a lógica apropriada no JavaScript imperativo, que a cada linha de código se torna cada vez mais confuso e frágil.

Vantagens da abordagem moderna: previsibilidade, reutilização e combinação


A capacidade de usar uma única fonte de verdade é a vantagem mais importante desse modelo, mas tem outras vantagens. Definir os elementos de nossa página no código JavaScript significa que podemos reutilizar componentes (blocos individuais de uma página da web), impedindo-nos de copiar e colar o mesmo código HTML em vários locais. Se precisarmos alterar um componente, basta alterar seu código em apenas um lugar. Nesse caso, ocorrerão alterações em todas as cópias do componente (dentro de um ou mesmo em muitos aplicativos da Web, se usarmos componentes reutilizáveis).

Podemos pegar componentes simples e montá-los como cubos LEGO, criando componentes mais complexos e úteis sem tornar sua lógica muito confusa. E se usarmos componentes criados por outros desenvolvedores, poderemos acumular facilmente atualizações ou correções de bugs sem precisar reescrever nosso código.

O mesmo JavaScript, apenas no perfil


Esses benefícios têm uma desvantagem. Existem boas razões pelas quais as pessoas apreciam a separação de HTML e JavaScript. Como mencionei anteriormente, o abandono de arquivos HTML regulares complica o fluxo de trabalho para alguém que não trabalhou com JavaScript antes. Aqueles que anteriormente podiam fazer alterações de maneira independente no aplicativo da Web agora precisam adquirir habilidades complexas adicionais para manter sua autonomia ou até mesmo fazer parte da equipe.

Existem também falhas técnicas. Por exemplo, algumas ferramentas, como linters e analisadores, aceitam apenas HTML normal como entrada e trabalhar com plug-ins JavaScript de terceiros pode ser mais difícil. Além disso, o JavaScript não é o melhor idioma, mas é um padrão uniforme aceito para navegadores da web. Novas ferramentas e recursos melhoram, mas ainda existem algumas armadilhas que você precisa conhecer antes de trabalhar com ela.

Outro problema em potencial: quando a estrutura semântica da página é dividida em componentes abstratos, o desenvolvedor pode parar de pensar em quais elementos HTML serão gerados como resultado. Tags HTML específicas, como seção e aparte, têm sua própria semântica, que é perdida ao usar tags de uso geral, como div e span, mesmo que visualmente tenham a mesma aparência na página. Isso é especialmente importante para garantir a disponibilidade do aplicativo Web para diferentes categorias de usuários.

Por exemplo, isso afetará o comportamento do leitor de tela para usuários com deficiência visual. Talvez essas não sejam as tarefas mais interessantes para o desenvolvedor, mas os desenvolvedores de JavaScript devem sempre lembrar que preservar a semântica do HTML nesse caso é a tarefa mais importante .

Necessidade consciente vs tendência inconsciente


Recentemente, o uso de estruturas em todos os projetos se tornou uma tendência. Algumas pessoas acreditam que a separação de HTML e JavaScript está desatualizada, mas não está. Para um site estático simples que não requer interação complicada do usuário, isso é correto. Os fãs mais fervorosos do React podem discordar de mim aqui, mas se todo o seu JavaScript criar uma página da web não interativa, você não deve usá-la. O JavaScript não carrega tão rápido quanto o HTML comum. Portanto, se você não definir a tarefa de obter nova experiência de desenvolvimento ou melhorar a confiabilidade do código, o JavaScript aqui fará mais mal do que bem.

Além disso, não há necessidade de escrever todo o site no React. Ou Vue! Ou o que mais existe ... Muitas pessoas não sabem disso, porque todos os tutoriais mostram basicamente como usar o React para desenvolver um site a partir do zero. Se você tiver apenas um pequeno widget complexo em um site simples, poderá usar o React para um componente . Você nem sempre precisa se preocupar com o webpack, Redux, Gatsby ou qualquer outra coisa que alguém recomende como "melhores práticas" lá.

Mas se o aplicativo for bastante complexo, vale a pena usar uma abordagem declarativa moderna. React é a melhor solução? Não. Ele já tem concorrentes fortes. E então mais e mais aparecerão ... Mas a programação declarativa não vai a lugar algum e, em alguma nova estrutura, essa abordagem provavelmente será repensada e implementada ainda melhor.


All Articles