3 คะแนน โดย GN⁺ 2024-08-17 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

ตัวอย่างของ Vanilla JSX

ถ้า JSX คืนค่าเป็นองค์ประกอบ DOM ล่ะ?

  • ฟังก์ชัน ClickMe มีหน้าที่สร้างปุ่มและแสดงจำนวนครั้งที่คลิก
  • ทุกครั้งที่คลิกปุ่ม ข้อความจะถูกอัปเดต
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;
}

การนำกลับมาใช้ซ้ำ

  • สามารถใช้คอมโพเนนต์ ClickMe ได้หลายครั้ง โดยแต่ละตัวจะคงสถานะของตัวเองไว้
import ClickMe from "./sample1.js";
export default () => <>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
</>;

การสร้าง DOM tree แบบโต้ตอบได้

  • สามารถใช้คลาส TodoInput และ TodoList เพื่อจัดการรายการสิ่งที่ต้องทำได้
  • เพิ่มรายการและคลิกเพื่อลบออกได้
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}
  </>;
};

การประมวลผลข้อมูลขนาดใหญ่

  • ฟังก์ชัน FindNames ประมวลผลและกรองข้อมูลจำนวนมากเพื่อแสดงผลลัพธ์
  • อัปเดตรายการที่ตรงกันแบบเรียลไทม์ตามค่าที่ป้อน
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>');
}

แนะนำ imlib

  • imlib เป็นไลบรารีที่พัฒนาขึ้นสำหรับ immaculatalibrary.com
  • ถูกใช้ในการสร้าง minigamemaker.com และเว็บไซต์ที่คุณกำลังอ่านอยู่ในตอนนี้
  • ถูกพัฒนาขึ้นเพราะสถานะเดิมที่มีอยู่นั้นไม่เพียงพอ และเป็นวิธีที่ผู้พัฒนาชอบที่สุดในการสร้างแอป

สรุปโดย GN⁺

  • บทความนี้อธิบายวิธีสร้างและโต้ตอบกับองค์ประกอบ DOM โดยตรงด้วย JSX
  • นำเสนอวิธีจัดการข้อมูลจำนวนมากอย่างมีประสิทธิภาพได้โดยไม่ต้องใช้ virtual DOM แบบเดิม
  • ไลบรารี imlib ช่วยให้พัฒนาแอปได้ด้วยวิธีที่เรียบง่ายและตรงไปตรงมา
  • โปรเจกต์อื่นที่มีความสามารถคล้ายกัน ได้แก่ React, Vue.js เป็นต้น

1 ความคิดเห็น

 
GN⁺ 2024-08-17
ความคิดเห็นจาก Hacker News
  • ขอบคุณที่สนใจโปรเจกต์นี้

    • เริ่มโปรเจกต์นี้เพราะไม่พอใจกับสภาพของ SSGs ตลอด 10 ปีที่ผ่านมา
    • ปกติสร้างเว็บไซต์แบบสแตติกเป็นหลัก และต้องการสิ่งที่เรียบง่ายและตรงไปตรงมา
    • JSX ดูเหมือนจะเหมาะ แต่ก็เหนื่อยกับความซับซ้อนของเฟรมเวิร์ก JSX อย่าง React
    • จึงสร้าง SSG ที่เรนเดอร์ JSX เป็นสตริง และขยายให้เรนเดอร์เป็นองค์ประกอบ DOM ในเบราว์เซอร์ได้
    • ใช้งานได้ดีกับคอมโพเนนต์ที่ใช้ร่วมกันในบางเลย์เอาต์
    • ทำงานได้ดีกับ SEO ด้วย
    • การรองรับจาก IDE ยังไม่สมบูรณ์
  • ถ้าคืนค่าเป็นโหนด DOM จริง ข้อดีใหญ่ของ JSX ก็จะหายไป

    • ต้องคืนค่าคำอธิบายของ DOM เพื่อให้ประเมินเทมเพลตใหม่ตามสถานะใหม่และอัปเดตได้อย่างมีประสิทธิภาพ
    • ตัวอย่างใช้ DOM API แบบเชิงคำสั่งในการอัปเดต
    • ข้อดีหลักของ VDOM คือการวนซ้ำรายการในเทมเพลต
    • ปัญหาของ VDOM คือ diffing ที่ช้า
  • ต้นกำเนิดของ JSX มาจาก XHP ของ Facebook

    • XHP ได้แรงบันดาลใจจาก E4X
  • ตัวอย่างสุดท้ายไม่ทำงานบน Firefox

    • บน Edge ใช้งานได้ แต่บน Firefox เกิดข้อผิดพลาด
  • คล้ายกับ Vanilla TSX มาก

    • มีตัวอย่างแอปที่เขียนด้วย Vanilla TSX ให้ดู
  • ทำให้นึกถึง Action Script 3

    • XML เป็นแกนหลักของภาษา และแม้จะสนุก แต่ก็ไม่ได้กลายเป็น ES4
    • ต้องใช้เวลากว่า 10 ปีจึงจะไปถึงระดับใกล้เคียงกันด้วย Typescript และ JSX
  • ตัวอย่างไม่ได้แสดงคอมโพเนนต์ที่มี props ซึ่งอาจเปลี่ยนไปตามเวลา

    • ดูเหมือนจะขยายไปเป็นแอปที่ซับซ้อนกว่านี้ได้ยาก
  • ฉันก็เคยสร้าง UI library ที่อิงกับนิพจน์เทมเพลต jsx ซึ่งสร้างโหนด DOM จริงเหมือนกัน

    • ผูก model object เข้ากับแอตทริบิวต์เพื่อลด boilerplate ของ event handler แบบเชิงคำสั่ง
    • คิดว่าเป็นไอเดียที่ดี
  • ไม่เข้าใจเสน่ห์ของ JSX

    • มีวิธีอื่นที่ง่ายกว่าและให้ทั้งลูป การแทรกตัวแปร ฯลฯ แบบอัตโนมัติ
  • แนะนำ Imba

    • ดูเหมือนจะไม่ค่อยนิยมเพราะนักพัฒนา JS มักตกเป็นเป้าการตลาดของ Faang ได้ง่าย