3 puntos por GN⁺ 2024-08-17 | 1 comentarios | Compartir por WhatsApp

Ejemplos de JSX vainilla

¿Y si JSX devolviera elementos del DOM?

  • La función ClickMe crea un botón y muestra la cantidad de clics
  • El texto se actualiza cada vez que se hace clic en el botón
export default function ClickMe() {
  let i = 0;
  const el = <button>Click me</button> as HTMLButtonElement;
  el.onclick = (e) => {
    el.textContent = `Clicked ${++i} times`;
  };
  return el;
}

Reutilización

  • El componente ClickMe puede usarse varias veces y mantener un estado distinto en cada instancia
import ClickMe from "./sample1.js";
export default () => <>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
</>;

Creación de un árbol DOM interactivo

  • Se puede administrar una lista de tareas usando las clases TodoInput y TodoList
  • Se pueden agregar elementos y eliminarlos con un clic
function TodoInput(attrs: { add: (v: string) => void }) {
  const input = <input /> as HTMLInputElement;
  input.placeholder = 'Add todo item...';
  input.onkeydown = (e) => {
    if (e.key === 'Enter') {
      attrs.add(input.value);
      input.value = '';
    }
  };
  return input;
}

class TodoList {
  ul = <ul class='todolist' /> as HTMLUListElement;
  add(v: string) {
    const item = <li>{v}</li> as HTMLLIElement;
    item.onclick = () => item.remove();
    this.ul.append(item);
  }
}

export default () => {
  const list = new TodoList();
  list.add('foo');
  list.add('bar');
  return <>
    <TodoInput add={(v) => list.add(v)} />
    {list.ul}
  </>;
};

Procesamiento de grandes volúmenes de datos

  • La función FindNames procesa y filtra grandes volúmenes de datos para mostrar resultados
  • Actualiza en tiempo real los elementos coincidentes según el valor de entrada
import { data } from "../fetch-dataset.js";
export default function FindNames() {
  const status = <p style='margin:1em 0' /> as HTMLParagraphElement;
  const results = <ul /> as HTMLUListElement;
  const input = <input value='eri(c|k)a?' autocomplete='new-password' oninput={updateMatches} /> as HTMLInputElement;
  updateMatches();

  function updateMatches() {
    const matched = (data.entries().filter(([k]) => k.match(input.value)).toArray());
    const matches = (Iterator.from(matched).map(match => <Item regex={input.value} match={match} />).take(30));
    results.replaceChildren(...matches);
    status.textContent = `${matched.length} / ${data.size}`;
  }

  return <div class='sample4'>
    {input}
    {status}
    {results}
  </div>;
}

function Item(attrs: { match: [string, number], regex: string }) {
  const [name, count] = attrs.match;
  const total = <small style='color:#fff3'>({count})</small>;
  return <li>
    <span innerHTML={highlight(name, attrs.regex)} /> {total}
  </li>;
}

function highlight(str: string, regex: string) {
  if (!regex) return str;
  const r = new RegExp(`(${regex})`, 'gi');
  return str.replace(r, '<span class="match">$1</span>');
}

Introducción a imlib

  • imlib es una librería desarrollada para immaculatalibrary.com
  • Se usa para construir minigamemaker.com y el sitio web que estás leyendo ahora
  • Fue desarrollada porque el estado existente no era suficiente, y es la forma preferida de crear apps

Resumen de GN⁺

  • Este artículo explica cómo crear e interactuar directamente con elementos del DOM usando JSX
  • Presenta una forma de procesar grandes volúmenes de datos de manera eficiente sin usar un DOM virtual
  • La librería imlib permite desarrollar apps de una manera simple e intuitiva
  • Otros proyectos con funciones similares incluyen React, Vue.js, etc.

1 comentarios

 
GN⁺ 2024-08-17
Comentarios en Hacker News
  • Gracias por interesarse en el proyecto

    • Empecé el proyecto porque estaba inconforme con el estado de los SSGs durante los últimos 10 años
    • Principalmente hago sitios web estáticos y quería algo simple e intuitivo
    • JSX parecía encajar, pero me cansó la complejidad de los frameworks JSX como React
    • Hice un SSG que renderiza JSX como cadenas, y lo extendí para que lo renderice como elementos DOM en el navegador
    • En algunos layouts funciona bien con componentes compartidos
    • También funciona bien para SEO
    • El soporte del IDE no es perfecto
  • Si devuelve nodos DOM reales, se pierde una gran ventaja de JSX

    • Debería devolver una descripción del DOM para poder reevaluar la plantilla con un nuevo estado y actualizar eficientemente
    • El ejemplo actualiza usando la API imperativa del DOM
    • La principal ventaja del VDOM es iterar elementos en las plantillas
    • El problema del VDOM es el diffing lento
  • El origen de JSX viene de XHP de Facebook

    • XHP se inspiró en E4X
  • El ejemplo final no funciona en Firefox

    • En Edge funciona, pero en Firefox da error
  • Es muy similar a Vanilla TSX

    • Se ofrece un ejemplo de app escrita con Vanilla TSX
  • Hace recordar a Action Script 3

    • XML era parte central del lenguaje y era divertido, pero no logró convertirse en ES4
    • Tomó más de 10 años llegar a un nivel similar con Typescript y JSX
  • Los ejemplos no muestran componentes con props que puedan cambiar con el tiempo

    • Parece que será difícil escalarlo a apps más complejas
  • Yo también hice una librería de UI basada en expresiones de plantillas jsx que crean nodos DOM reales

    • Vincula objetos del modelo a propiedades para eliminar el boilerplate de manejadores de eventos imperativos
    • Me parece una buena idea
  • No entiendo el atractivo de JSX

    • Hay otras formas más fáciles que ya dan automáticamente bucles, inserción de variables, etc.
  • Recomiendan Imba

    • Parece que no es popular porque a los desarrolladores de JS los convence fácilmente el marketing de FAANG