3 pontos por GN⁺ 2024-08-17 | 1 comentários | Compartilhar no WhatsApp

Exemplos de Vanilla JSX

E se JSX retornasse elementos DOM?

  • A função ClickMe cria um botão e exibe a contagem de cliques
  • O texto é atualizado cada vez que o botão é clicado
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;
}

Reutilização

  • O componente ClickMe pode ser usado várias vezes, mantendo estados diferentes para cada instância
import ClickMe from "./sample1.js";
export default () => <>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
</>;

Criação de uma árvore DOM interativa

  • É possível gerenciar uma lista de tarefas usando as classes TodoInput e TodoList
  • Itens podem ser adicionados e removidos ao clicar neles
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}
  </>;
};

Processamento de grandes volumes de dados

  • A função FindNames processa e filtra grandes volumes de dados para exibir os resultados
  • Os itens correspondentes são atualizados em tempo real conforme o 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>');
}

Introdução ao imlib

  • imlib é uma biblioteca desenvolvida para o immaculatalibrary.com
  • Ela é usada para construir o minigamemaker.com e o site que você está lendo agora
  • Foi desenvolvida porque o estado da arte existente não era suficiente, e é a forma preferida de criar apps

Resumo do GN⁺

  • Este artigo explica como criar e interagir diretamente com elementos DOM usando JSX
  • Ele apresenta uma forma de processar grandes volumes de dados com eficiência sem usar um virtual DOM
  • A biblioteca imlib permite desenvolver apps de maneira simples e intuitiva
  • Outros projetos com funcionalidades semelhantes incluem React e Vue.js

1 comentários

 
GN⁺ 2024-08-17
Comentários do Hacker News
  • Obrigado pelo interesse no projeto

    • Comecei o projeto por estar insatisfeito com o estado dos SSGs nos últimos 10 anos
    • Crio principalmente sites estáticos e queria algo simples e intuitivo
    • JSX parecia adequado, mas eu estava cansado da complexidade de frameworks JSX como React
    • Criei um SSG que renderiza JSX em strings e expandi isso para renderizar elementos DOM no navegador
    • Em alguns layouts, isso funciona bem com componentes compartilhados
    • Também funciona bem para SEO
    • O suporte da IDE não é perfeito
  • Se retornar nós DOM reais, uma grande vantagem do JSX se perde

    • É preciso retornar uma descrição do DOM para reavaliar o template com o novo estado e atualizar de forma eficiente
    • O exemplo faz atualizações usando a API imperativa do DOM
    • O principal benefício do VDOM é repetir itens no template
    • O problema do VDOM é o diffing lento
  • A origem do JSX vem do XHP do Facebook

    • O XHP foi inspirado no E4X
  • O exemplo final não funciona no Firefox

    • No Edge funciona, mas no Firefox ocorre um erro
  • É muito parecido com Vanilla TSX

    • Há um exemplo de app escrito com Vanilla TSX
  • Lembra Action Script 3

    • XML era central na linguagem, e era divertido, mas não virou ES4
    • Levou mais de 10 anos para atingir um nível parecido com TypeScript e JSX
  • Os exemplos não mostram componentes com props que podem mudar ao longo do tempo

    • Parece que haveria dificuldade para escalar isso para apps mais complexos
  • Eu também criei uma biblioteca de UI baseada em expressões de template JSX que geram nós DOM reais

    • Vinculei objetos de modelo a propriedades para eliminar boilerplate de handlers de eventos imperativos
    • Acho que é uma boa ideia
  • Não entendo o apelo do JSX

    • Outros métodos que já fornecem automaticamente loops, interpolação de variáveis etc. são mais fáceis
  • Recomendo Imba

    • Parece não ser popular porque desenvolvedores JS caem facilmente no marketing da Faang