Por qué JavaScript devora HTML: ejemplos de código

El desarrollo web está en constante evolución. Recientemente, una tendencia se ha vuelto popular, lo que básicamente contradice la idea generalmente aceptada de cómo desarrollar aplicaciones web. Algunos tienen grandes esperanzas para él, mientras que otros están decepcionados. Cada uno tiene sus propias razones para esto, que en pocas palabras es difícil de explicar.



El código de una página web tradicionalmente consta de tres secciones, cada una de las cuales cumple con sus deberes: el código HTML define la estructura y la semántica, el código CSS determina la apariencia y el código JavaScript determina su comportamiento. En los equipos que involucran a diseñadores, desarrolladores de HTML / CSS y desarrolladores de JavaScript, esta separación es natural: los diseñadores definen elementos visuales y una interfaz de usuario, los desarrolladores de HTML y CSS colocan estos elementos visuales en una página en un navegador, y los desarrolladores de JavaScript agregan la interacción del usuario a une todo y "haz que funcione". Todos pueden trabajar en sus tareas sin interferir en el código de las otras dos categorías de desarrolladores. Pero todo esto es cierto para el llamado "estilo antiguo".

En los últimos años, los desarrolladores de JavaScript comenzaron a determinar la estructura de la página en JavaScript, y no en HTML (por ejemplo, utilizando el marco React js ), lo que ayuda a simplificar la creación y el mantenimiento del código de interacción del usuario. Sin los frameworks js, desarrollar sitios web modernos es mucho más difícil. Por supuesto, cuando le dices a alguien que el código HTML escrito por él debe romperse en pedazos y mezclarse con JavaScript, con el que está muy familiarizado, esto (por razones obvias) se puede percibir con hostilidad. Como mínimo, el interlocutor preguntará por qué necesitamos esto y cómo nos beneficiaremos de esto.

Como desarrollador de JavaScript en un equipo multifuncional, a veces me hacen esta pregunta, y a menudo me resulta difícil responderla. Todos los materiales que encontré sobre este tema están escritos para una audiencia que ya está familiarizada con JavaScript. Y esto no es muy bueno para aquellos que se especializan exclusivamente en HTML y CSS. Pero es probable que el patrón HTML-in-JS (o algo más que proporcione los mismos beneficios) tenga demanda durante algún tiempo, por lo que creo que esto es algo importante que todos los involucrados en el desarrollo web deberían entender.

En este artículo daré ejemplos de código para aquellos que estén interesados, pero mi objetivo es explicar este enfoque para que pueda entenderse sin ellos.

Likbez: HTML, CSS y JavaScript


Para maximizar la audiencia de este artículo, quiero hablar brevemente sobre el papel que juegan estos idiomas en la creación de páginas web y qué tipo de separación existió inicialmente. Si todos lo saben, pueden omitir esta sección.

HTML: para estructura y semántica


El código HTML (lenguaje de marcado de hipertexto) define la estructura y la semántica del contenido que se colocará en la página. Por ejemplo, el código HTML de este artículo contiene el texto que está leyendo ahora y, de acuerdo con la estructura especificada, este texto se coloca en un párrafo separado, después del encabezado y antes de pegar CodePen .

Por ejemplo, cree una página web simple con una lista de compras:



Podemos guardar este código en un archivo, abrirlo en un navegador web y el navegador mostrará el resultado. Como puede ver, el código HTML en este ejemplo es una página que contiene el encabezado “Lista de compras” (Artículos de compras (2 artículos)), un cuadro de texto de entrada, un botón “Agregar artículo” y una lista de dos artículos (“Huevos” y "Aceite"). El usuario ingresará la dirección en su navegador web, luego el navegador solicitará este código HTML al servidor, lo descargará y lo mostrará. Si ya hay elementos en la lista, el servidor puede enviar HTML con elementos listos, como en este ejemplo.

Intente escribir algo en el campo de entrada y haga clic en el botón "Agregar elemento". Verás que no pasa nada. El botón no está asociado con ningún código que pueda cambiar HTML, y HTML no puede cambiar nada por sí mismo. Volveremos a esto en un minuto.

CSS: para cambiar el aspecto


El código CSS (hojas de estilo en cascada) define la apariencia de la página. Por ejemplo, el CSS de este artículo define la fuente, el espaciado y el color del texto que está leyendo.

Es posible que haya notado que nuestro ejemplo de lista de compras parece muy simple. HTML no permite que se especifiquen espacios, tamaños de fuente y colores. Por eso usamos CSS. Podríamos agregar código CSS para esta página para decorarlo un poco:



como puede ver, este código CSS cambió el tamaño y el grosor de los caracteres de texto, así como el color de fondo. Un desarrollador puede, por analogía, escribir reglas para su propio estilo, y se aplicarán secuencialmente a cualquier estructura HTML: si agregamos elementos de sección, botón o ul a esta página , se aplicarán los mismos cambios de fuente.
Pero el botón Agregar elemento todavía no hace nada: aquí solo necesitamos JavaScript.

JavaScript: para implementar el comportamiento


El código JavaScript define el comportamiento de elementos interactivos o dinámicos en una página. Por ejemplo, CodePen se escribe usando JavaScript.

Para que el botón Agregar elemento en nuestro ejemplo funcione sin JavaScript, necesitaríamos usar un código HTML especial para forzarlo a enviar datos de vuelta al servidor ( <form action \ u003d '...'> si está repentinamente interesado). Además, el navegador volverá a cargar la versión actualizada de todo el archivo HTML sin guardar el estado actual de la página. Si esta lista de compras fuera parte de una gran página web, todo lo que el usuario hiciera se perdería. No importa cuántos píxeles haya movido hacia abajo mientras lee el texto; cuando reinicie el servidor, volverá al principio, no importa cuántos minutos del video que vio; cuando reinicie, comenzará de nuevo.

Así solían funcionar todas las aplicaciones web: cada vez que un usuario interactuaba con una página web, parecía cerrar su navegador web y volver a abrirlo. Esto no importa mucho para un caso de estudio simple, pero para una página grande y compleja, que puede tardar un poco en cargar, este enfoque no es efectivo ni para el navegador ni para el servidor.

Si queremos cambiar algo en la página sin volver a cargar esta página por completo, debemos usar JavaScript:



ahora, cuando escribimos el texto en el campo de entrada y hacemos clic en el botón Agregar elemento, ¡nuestro nuevo elemento se agrega a la lista y se actualiza el número de elementos en la parte superior! En una aplicación real, también agregaríamos un código para enviar un nuevo elemento al servidor en segundo plano para que aparezca la próxima vez que se cargue la página.

La separación de JavaScript de HTML y CSS se justifica incluso en este sencillo ejemplo. Las interacciones más complejas funcionan así: se carga y muestra HTML, y posteriormente se lanza JavaScript para agregarle algo y cambiarlo. Sin embargo, a medida que crece la complejidad de la aplicación web, necesitamos monitorear cuidadosamente qué, dónde y cuándo cambia nuestro código JavaScript.

Si continuamos desarrollando esta aplicación con una lista de compras, podríamos agregar botones para editar o eliminar elementos de la lista. Supongamos que escribimos código JavaScript para un botón que elimina un elemento, pero olvidemos agregar código que actualice la información sobre el número total de elementos en la parte superior de la página. De repente, recibimos un error: después de que el usuario elimina el elemento, ¡el número total indicado en la página no coincidirá con la lista!

Tan pronto como notamos el error, lo arreglamos agregando la misma línea totalText.innerHTML de nuestro código para Agregar elemento al código para Eliminar elemento. Ahora tenemos el mismo código, que está duplicado en varios lugares. Más adelante, digamos, queremos cambiar este código para que en lugar de “(2 elementos)” en la parte superior de la página muestre “Elementos: 2”. Debemos asegurarnos de no olvidar actualizar este código en los tres lugares: en HTML, en el código JavaScript para el botón Agregar elemento y en el código JavaScript para el botón Eliminar elemento. Si no lo hacemos, tendremos otro error, por lo que este texto cambiará dramáticamente después de interactuar con el usuario.

Ya en este simple ejemplo, vemos lo fácil que es confundirse en el código. Por supuesto. Existen enfoques y prácticas para simplificar el código JavaScript para que sea más fácil resolver este problema. Sin embargo, a medida que las cosas se vuelven más complicadas, tendremos que continuar la reestructuración y reescribir constantemente el proyecto para que pueda desarrollarse y mantenerse fácilmente. Si bien HTML y JavaScript se almacenan por separado, puede tomar mucho esfuerzo garantizar la sincronización entre los dos. Esta es una de las razones por las que los nuevos marcos de JavaScript como React se han vuelto populares: están diseñados para proporcionar una relación más formal y eficiente entre HTML y JavaScript. Para entender cómo funciona esto, primero debemos profundizar un poco más en la informática.

Programación imperativa vs declarativa


La clave para entender es la diferencia de pensamiento. La mayoría de los lenguajes de programación le permiten seguir un solo paradigma, aunque algunos admiten dos a la vez. Es importante comprender ambos paradigmas para apreciar la principal ventaja de HTML-in-JS desde el punto de vista del desarrollador de JavaScript.

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

  • . , . , , «» (), , - . , . (, React), , , . , , , , . , :
    • « XYZ. , , .
    • Ejemplo: este elemento tiene una clase .selected si el usuario la seleccionó.


HTML es un lenguaje declarativo


Olvídate de JavaScript por un momento. Aquí hay un hecho importante: HTML es un lenguaje declarativo. En el archivo HTML, puede declarar algo como:

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

Cuando el navegador web lee este código HTML, determinará independientemente los pasos necesarios y los realizará:

  1. Crea un elemento de sección .
  2. Cree un elemento de encabezado de nivel 1 ( h1 ).
  3. Establezca el texto del elemento del título en "Hola".
  4. Coloque el elemento de título en el elemento de sección.
  5. Crea un elemento de párrafo ( p ).
  6. Establezca el texto del elemento de párrafo en "Mi nombre es Mike".
  7. Coloque un elemento de párrafo en un elemento de sección .
  8. Coloque el elemento de sección en un documento HTML.
  9. Mostrar el documento en la pantalla.

Para el desarrollador web, no importa exactamente cómo hace estas cosas el navegador: lo único que importa es lo que hace. Este es un gran ejemplo para ilustrar la diferencia entre los dos paradigmas de programación. En resumen, HTML es una abstracción declarativa envuelta alrededor de un motor de representación de navegador web implementado imperativamente. Le importa cómo, así que solo debes preocuparte por qué. Puedes disfrutar de la vida mientras escribes HTML declarativo porque las buenas personas de Mozilla, Google y Apple escribieron un código imperativo para ti cuando crearon tu navegador web.

JavaScript es un lenguaje imperativo


Ya vimos un ejemplo simple de JavaScript imperativo en el ejemplo de la lista de compras anterior, y describí cómo la complejidad de las funciones de la aplicación afecta el esfuerzo requerido para implementarlas y la probabilidad de errores en esta implementación.

Ahora veamos un problema un poco más complejo y veamos cómo se puede simplificar usando un enfoque declarativo. Imagine una página web que contiene lo siguiente:

  • una lista de banderas marcadas, cada línea de las cuales cambia su color cuando se selecciona;
  • texto a continuación, por ejemplo, "1 de 4 seleccionados", que debe actualizarse cuando se cambian las banderas;
  • Seleccione el botón Todo, que debe deshabilitarse si todas las casillas de verificación ya están seleccionadas;
  • Seleccione el botón Ninguno, que debe deshabilitarse si las casillas de verificación no están seleccionadas.

Aquí hay una implementación en HTML, CSS y 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();
  });
});

Dolor de cabeza como es


Para implementar esta función usando JavaScript imperativo, necesitamos darle al navegador algunas instrucciones detalladas. Esta es una descripción verbal del código del ejemplo anterior.
En nuestro HTML, declaramos la estructura de la página original:
  • Hay cuatro elementos de fila (una fila de una tabla, es una lista), cada uno de los cuales contiene una bandera. La tercera bandera está marcada.
  • Hay un texto "1 de 4 seleccionados".
  • Hay un botón Seleccionar todo que está activado.
  • Hay un botón Seleccionar ninguno, que está deshabilitado.

En nuestro JavaScript, escribimos instrucciones sobre lo que debe cambiarse cuando ocurre cada uno de estos eventos:
Cuando un indicador cambia de no marcado a marcado:
  • Busque la fila que contiene la casilla de verificación y agregue la clase CSS .seleccionada.
  • Encuentre todas las banderas en la lista y calcule cuántas están marcadas y cuántas no.
  • Encuentre el texto y actualícelo, indicando el número correcto de compras seleccionadas y su número total.
  • Busque el botón Seleccionar ninguno y actívelo si estaba deshabilitado.
  • Si todas las casillas de verificación están ahora marcadas, busque el botón Seleccionar todo y desactívelo.

Cuando una bandera cambia de marcado a no marcado:
  • Encuentre la fila que contiene la bandera y elimine la clase .selected de ella.
  • Busque todas las casillas de verificación en la lista y calcule cuántas de ellas están marcadas y cuántas no.
  • Busque el elemento de texto del currículum y actualícelo con el número verificado y el total.
  • Busque el botón Seleccionar todo y actívelo si estaba deshabilitado.
  • Si todas las casillas están desmarcadas, busque el botón Seleccionar ninguno y desactívelo.

Cuando se presiona el botón Seleccionar todo:
  • Busque todas las casillas de verificación en la lista y márquelas.
  • Busque todas las filas en la lista y agregue la clase .selected a ellas.
  • Encuentra el texto y actualízalo.
  • Busque el botón Seleccionar todo y desactívelo.
  • Busque el botón Seleccionar ninguno y actívelo.

Cuando se presiona el botón Seleccionar Ninguno:
  • Busque todas las casillas de verificación en la lista y borre todas las casillas de verificación.
  • Busque todas las filas de la lista y elimine la clase .selected de ellas.
  • Encuentre el elemento de texto del currículum y actualícelo.
  • Busque el botón Seleccionar todo y actívelo.
  • Busque el botón Seleccionar ninguno y desactívelo.

Wow ... Eso es mucho, ¿verdad? Bueno, mejor no olvidemos escribir código para todas las situaciones posibles. Si olvidamos o dañamos alguna de estas instrucciones, recibimos un error: los totales no coinciden con las casillas de verificación, o el botón que no hace nada cuando hace clic en él, o la fila seleccionada obtiene el color incorrecto o algo, está activada aún, lo que no hemos pensado y no sabremos hasta que el usuario se queje.

Realmente tenemos un gran problema aquí: no existe una entidad que contenga información completa sobre el estadode nuestra aplicación (en este caso, esta es la respuesta a la pregunta "¿qué banderas están marcadas?") y sería responsable de actualizar esta información. Las banderas, por supuesto, saben si están marcadas, pero el código CSS para las filas de la tabla, el texto y cada botón también deben ser conscientes de esto. Cinco copias de esta información se almacenan por separado en todo el HTML, y cuando cambia en cualquiera de estos lugares, el desarrollador de JavaScript debe captar esto y escribir código imperativo para sincronizar con los cambios en otros lugares.

Y este sigue siendo un ejemplo simple de un componente de página pequeña. Incluso si este conjunto de instrucciones parece un dolor de cabeza, imagine lo complejo y frágil que se vuelve una aplicación web más grande cuando necesita implementar todo esto en JavaScript imperativo. Para muchas aplicaciones web modernas y complejas, esta solución no se escala de la palabra "completamente".

Estamos buscando la fuente de la verdad.


Herramientas como React permiten el uso declarativo de JavaScript. Así como HTML es una abstracción declarativa sobre las instrucciones para mostrar en un navegador web, React es una abstracción declarativa sobre JavaScript.

¿Recuerda cómo HTML nos permite centrarnos en la estructura de la página en lugar de los detalles de implementación, y cómo muestra el navegador esta estructura? Del mismo modo, cuando usamos React, podemos centrarnos en la estructura, definiéndola en función de los datos almacenados en un lugar. Este proceso se denomina enlace unidireccional, y la ubicación de los datos del estado de la aplicación se denomina "fuente única de verdad". Cuando la fuente de la verdad cambia, React actualizará automáticamente la estructura de la página. Se encargará de los pasos necesarios detrás del escenario, como lo hace un navegador web para HTML. Aunque React se usa como un ejemplo aquí, este enfoque también funciona para otros marcos como Vue.

Volvamos a nuestra lista de casillas de verificación del ejemplo anterior. En este caso, la "verdad" que queremos saber es bastante concisa: ¿qué banderas están marcadas? Otros detalles (por ejemplo, texto, color de líneas, qué botones están activados) ya son información obtenida sobre la base de la fuente de la verdad. ¿Y por qué deberían tener su propia copia de esta información? Simplemente deben usar una única fuente de verdad de solo lectura, y todos los elementos de la página deben "simplemente saber" qué casillas de verificación están marcadas y comportarse en consecuencia. Puede decir que las filas de la tabla, el texto y los botones deberían poder responder automáticamente a una casilla de verificación dependiendo de si está marcada o no ("¿ve qué está pasando allí?")

Dime lo que quieres (lo que realmente quieres)


Para implementar esta página con React, podemos reemplazar la lista con algunas descripciones simples de hechos:

  • Hay una lista de valores verdaderos / falsos llamada checkboxValues ​​que muestra qué campos están marcados.
    • Ejemplo: checkboxValues ​​\ u003d [falso, falso, verdadero, falso]
    • Esta lista muestra que tenemos cuatro banderas, solo la tercera está configurada.

  • Para cada valor en checkboxValues ​​en la tabla, hay una fila que:
    • tiene una clase CSS llamada .selected si el valor es verdadero, y
    • contiene una bandera que se verifica si el valor es verdadero.

  • Hay un elemento de texto que contiene el texto "{x} de {y} seleccionado", donde {x} es el número de valores verdaderos en checkboxValues, y {y} es el número total de valores en checkboxValues.
  • Hay un botón Seleccionar todo que está habilitado si checkboxValues ​​tiene valores falsos.
  • Select None, , checkboxValues ​​ true.
  • , checkboxValues.
  • Select All , checkboxValues ​​ true.
  • Select None checkboxValues ​​ false.

Notarás que los últimos tres párrafos siguen siendo instrucciones imperativas ("Cuando esto suceda, hazlo"), pero este es el único código imperativo que necesitamos escribir. Estas son tres líneas de código, y todas actualizan una sola fuente de verdad.

El resto son declaraciones declarativas ("hay ..."), que ahora están integradas directamente en la definición de la estructura de la página. Para hacer esto, escribimos código para nuestros elementos usando una extensión especial de sintaxis de JavaScript: JavaScript XML (JSX). Se parece a HTML: JSX le permite usar una sintaxis similar a HTML para describir la estructura de la interfaz, así como JavaScript normal. Esto nos permite mezclar la lógica JS con la estructura HTML, por lo que la estructura puede ser diferente en cualquier momento. Todo depende del contenido de checkboxValues.

Reescribimos nuestro ejemplo en 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 se ve peculiar. Cuando encontré esto por primera vez, me pareció que era simplemente imposible hacerlo. Mi reacción inicial fue: "¿Qué? ¡HTML no puede estar dentro del código JavaScript! " Y no fui el único. Sin embargo, esto no es HTML, sino JavaScript disfrazado de HTML. De hecho, esta es una solución poderosa.

¿Recuerdas esas 20 instrucciones imperativas anteriores? Ahora tenemos tres de ellos. El resto (interno) instrucciones imperativas React se ejecuta para nosotros detrás de escena, cada vez que la casilla de verificación Valores cambia.

Con este código, la situación ya no puede ocurrir cuando el texto o el color de la línea no coinciden con las casillas de verificación, o cuando el botón está activado, aunque debería estar deshabilitado. Hay toda una categoría de errores que ahora simplemente no pueden ocurrir en nuestra aplicación web. Todo el trabajo se realiza sobre la base de una única fuente de verdad, y los desarrolladores podemos escribir menos código y dormir mejor por la noche. Bueno, desarrolladores de JavaScript, al menos ...

JavaScript derrotó a HTML: hambriento


A medida que las aplicaciones web se vuelven más complejas, mantener la separación clásica de tareas entre HTML y JavaScript se está volviendo más doloroso. HTML fue diseñado originalmente para páginas web estáticas. Para agregar funciones interactivas más complejas allí, es necesario implementar la lógica apropiada en JavaScript imperativo, que con cada línea de código se vuelve más confuso y frágil.

Ventajas del enfoque moderno: previsibilidad, reutilización y combinación.


La capacidad de usar una sola fuente de verdad es la ventaja más importante de este modelo, pero tiene otras ventajas. Definir los elementos de nuestra página en código JavaScript significa que podemos reutilizar componentes (bloques individuales de una página web), evitando que copiemos y peguemos el mismo código HTML en varios lugares. Si necesitamos cambiar un componente, simplemente cambie su código en un solo lugar. En este caso, se producirán cambios en todas las copias del componente (dentro de una o incluso en muchas aplicaciones web, si usamos componentes reutilizables en ellas).

Podemos tomar componentes simples y juntarlos como cubos LEGO, creando componentes más complejos y útiles sin hacer que su lógica sea demasiado confusa. Y si usamos componentes creados por otros desarrolladores, podemos acumular fácilmente actualizaciones o correcciones de errores sin tener que volver a escribir nuestro código.

El mismo JavaScript, solo en el perfil


Estos beneficios tienen un inconveniente. Hay buenas razones por las cuales las personas aprecian la separación de HTML y JavaScript. Como mencioné anteriormente, abandonar los archivos HTML normales complica el flujo de trabajo para alguien que no ha trabajado con JavaScript antes. Aquellos que anteriormente podían hacer cambios en la aplicación web de forma independiente, ahora deben adquirir habilidades complejas adicionales para mantener su autonomía, o incluso ubicarse en el equipo.

También hay fallas técnicas. Por ejemplo, algunas herramientas, como linters y analizadores, aceptan solo HTML normal como entrada, y trabajar con complementos de JavaScript de terceros puede ser más difícil. Además, JavaScript no es el mejor lenguaje, pero es un estándar uniforme aceptado para los navegadores web. Las nuevas herramientas y características lo mejoran, pero todavía hay algunas dificultades que debe conocer antes de trabajar con él.

Otro problema potencial: cuando la estructura semántica de la página se divide en componentes abstractos, el desarrollador puede dejar de pensar qué elementos HTML se generarán como resultado. Etiquetas HTML específicas como sección y aparte, tienen su propia semántica, que se pierden al usar etiquetas de uso general como div y span , incluso si se ven visualmente igual en la página. Esto es especialmente importante para garantizar la disponibilidad de la aplicación web para diferentes categorías de usuarios.

Por ejemplo, esto afectará el comportamiento del lector de pantalla para usuarios con discapacidad visual. Quizás estas no sean las tareas más interesantes para el desarrollador, pero los desarrolladores de JavaScript siempre deben recordar que preservar la semántica de HTML en este caso es la tarea más importante .

Necesidad consciente vs tendencia inconsciente


Recientemente, el uso de marcos en cada proyecto se ha convertido en una tendencia. Algunas personas creen que la separación de HTML y JavaScript está desactualizada, pero no lo está. Para un sitio web estático simple que no requiere interacción complicada del usuario, esto es justo. Los fanáticos de React más ardientes pueden estar en desacuerdo conmigo aquí, pero si todo lo que hace JavaScript es crear una página web no interactiva, no debe usarla. JavaScript no se carga tan rápido como el HTML normal. Por lo tanto, si no configura la tarea para obtener una nueva experiencia de desarrollo o mejorar la confiabilidad del código, JavaScript aquí hará más daño que bien.

Además, no es necesario escribir todo su sitio web en React. O Vue! O qué más hay ... Muchas personas no saben esto, porque todos los tutoriales básicamente muestran cómo usar React para desarrollar un sitio desde cero. Si solo tiene un pequeño widget complejo en un sitio web simple, puede usar React para un componente . No siempre tiene que preocuparse por webpack, Redux, Gatsby o cualquier otra cosa que alguien recomiende como "mejores prácticas" allí.

Pero si la aplicación es bastante compleja, vale la pena usar un enfoque declarativo moderno. ¿React es la mejor solución? No. Él ya tiene fuertes competidores. Y luego aparecerán más y más ... Pero la programación declarativa no irá a ninguna parte, y en algún marco nuevo, este enfoque probablemente será repensado e implementado aún mejor.


All Articles