3 điểm bởi GN⁺ 2024-08-17 | 1 bình luận | Chia sẻ qua WhatsApp

Các ví dụ của Vanilla JSX

Nếu JSX trả về phần tử DOM thì sao?

  • Hàm ClickMe tạo một nút bấm và hiển thị số lần được nhấp
  • Mỗi khi nhấp vào nút, nội dung văn bản sẽ được cập nhật
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;
}

Khả năng tái sử dụng

  • Có thể dùng component ClickMe nhiều lần để mỗi thành phần giữ trạng thái riêng
import ClickMe from "./sample1.js";
export default () => <>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
</>;

Tạo cây DOM tương tác

  • Có thể quản lý danh sách việc cần làm bằng các lớp TodoInputTodoList
  • Có thể thêm mục và nhấp để xóa chúng
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}
  </>;
};

Xử lý dữ liệu quy mô lớn

  • Hàm FindNames xử lý và lọc lượng dữ liệu lớn để hiển thị kết quả
  • Các mục khớp sẽ được cập nhật theo thời gian thực dựa trên giá trị đầu vào
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>');
}

Giới thiệu về imlib

  • imlib là thư viện được phát triển cho immaculatalibrary.com
  • Được dùng để xây dựng minigamemaker.com và website bạn đang đọc
  • Nó được tạo ra vì các trạng thái hiện có chưa đủ đáp ứng, và là cách được ưa thích nhất để xây dựng ứng dụng

Tóm tắt của GN⁺

  • Bài viết này giải thích cách dùng JSX để trực tiếp tạo và tương tác với các phần tử DOM
  • Đưa ra cách xử lý dữ liệu quy mô lớn hiệu quả mà không cần dùng virtual DOM
  • Thư viện imlib giúp phát triển ứng dụng theo cách đơn giản và trực quan
  • Các dự án khác có tính năng tương tự gồm React, Vue.js, v.v.

1 bình luận

 
GN⁺ 2024-08-17
Ý kiến trên Hacker News
  • Cảm ơn mọi người đã quan tâm đến dự án

    • Tôi bắt đầu dự án này vì không hài lòng với tình trạng của các SSG trong 10 năm qua
    • Tôi chủ yếu làm các website tĩnh và muốn một thứ đơn giản, trực quan
    • JSX có vẻ phù hợp, nhưng tôi đã mệt mỏi với sự phức tạp của các framework JSX như React
    • Tôi đã tạo một SSG render JSX thành chuỗi, rồi mở rộng nó để render thành các phần tử DOM trong trình duyệt
    • Trong một số layout, nó hoạt động tốt với các component dùng chung
    • Nó cũng hoạt động tốt cho SEO
    • Hỗ trợ IDE chưa hoàn hảo
  • Nếu trả về các DOM node thực tế thì một ưu điểm lớn của JSX sẽ biến mất

    • Cần trả về phần mô tả của DOM thì mới có thể đánh giá lại template với trạng thái mới và cập nhật hiệu quả
    • Ví dụ cập nhật bằng cách dùng DOM API kiểu mệnh lệnh
    • Lợi ích chính của VDOM là lặp qua các mục trong template
    • Vấn đề của VDOM là diffing chậm
  • Nguồn gốc của JSX bắt nguồn từ XHP của Facebook

    • XHP được truyền cảm hứng từ E4X
  • Ví dụ cuối cùng không hoạt động trên Firefox

    • Nó chạy trên Edge nhưng báo lỗi trên Firefox
  • Rất giống với Vanilla TSX

    • Có cung cấp ví dụ ứng dụng được viết bằng Vanilla TSX
  • Gợi nhớ đến Action Script 3

    • XML là cốt lõi của ngôn ngữ và khá thú vị, nhưng đã không trở thành ES4
    • Phải mất hơn 10 năm mới đạt đến mức tương tự với Typescript và JSX
  • Các ví dụ không cho thấy component có props có thể thay đổi theo thời gian

    • Có vẻ sẽ khó mở rộng sang các ứng dụng phức tạp hơn
  • Tôi cũng đã tạo một thư viện UI dựa trên các biểu thức template jsx tạo ra các DOM node thực tế

    • Tôi ràng buộc các đối tượng model vào thuộc tính để loại bỏ phần mã lặp của các event handler kiểu mệnh lệnh
    • Tôi nghĩ đó là một ý tưởng hay
  • Tôi không hiểu sức hấp dẫn của JSX

    • Có những cách khác dễ hơn và tự động hỗ trợ vòng lặp, chèn biến, v.v.
  • Khuyến nghị Imba

    • Có vẻ nó không phổ biến vì các nhà phát triển JS quá dễ bị marketing của Faang thuyết phục