3P by neo 3달전 | favorite | 댓글 1개

바닐라 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 트리 생성

  • TodoInputTodoList 클래스를 사용하여 할 일 목록을 관리할 수 있음
  • 항목을 추가하고 클릭하여 제거할 수 있음
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⁺의 정리

  • 이 글은 JSX를 사용하여 DOM 요소를 직접 생성하고 상호작용하는 방법을 설명함
  • 기존의 가상 DOM을 사용하지 않고도 효율적으로 대량 데이터를 처리할 수 있는 방법을 제시함
  • imlib 라이브러리는 간단하고 직관적인 방식으로 앱을 개발할 수 있게 해줌
  • 비슷한 기능을 가진 다른 프로젝트로는 React, Vue.js 등이 있음
Hacker News 의견
  • 프로젝트에 관심을 가져줘서 고마움

    • 지난 10년간 SSGs 상태에 불만을 느껴 프로젝트를 시작함
    • 주로 정적 웹사이트를 만들며, 간단하고 직관적인 것을 원했음
    • JSX가 적합해 보였지만 React 같은 JSX 프레임워크의 복잡성에 지침
    • JSX를 문자열로 렌더링하는 SSG를 만들었고, 이를 브라우저에서 DOM 요소로 렌더링하도록 확장함
    • 일부 레이아웃에서는 공유 컴포넌트로 잘 작동함
    • SEO에도 잘 작동함
    • IDE 지원이 완벽하지 않음
  • 실제 DOM 노드를 반환하면 JSX의 큰 장점이 사라짐

    • DOM의 설명을 반환해야 새로운 상태로 템플릿을 재평가하고 효율적으로 업데이트할 수 있음
    • 예제는 명령형 DOM API를 사용하여 업데이트함
    • VDOM의 주요 이점은 템플릿에서 항목을 반복하는 것임
    • VDOM의 문제는 느린 디핑(diffing)임
  • JSX의 기원은 Facebook의 XHP에서 비롯됨

    • XHP는 E4X에서 영감을 받음
  • 최종 예제가 Firefox에서 작동하지 않음

    • Edge에서는 작동하지만 Firefox에서는 오류 발생
  • Vanilla TSX와 매우 유사함

    • Vanilla TSX로 작성된 앱 예제 제공
  • Action Script 3을 떠올리게 함

    • XML이 언어의 핵심이었고, 재미있었지만 ES4가 되지 못함
    • Typescript와 JSX로 비슷한 수준에 도달하는 데 10년 이상 걸림
  • 예제들은 시간이 지나면서 변경될 수 있는 props를 가진 컴포넌트를 보여주지 않음

    • 더 복잡한 앱으로 확장하는 데 어려움이 있을 것 같음
  • 나도 실제 DOM 노드를 생성하는 jsx 템플릿 표현식을 기반으로 한 UI 라이브러리를 만듦

    • 모델 객체를 속성에 바인딩하여 명령형 이벤트 핸들러 보일러플레이트를 제거함
    • 좋은 아이디어라고 생각함
  • JSX의 매력을 이해하지 못함

    • 루프, 변수 삽입 등을 자동으로 제공하는 다른 방법이 더 쉬움
  • Imba를 추천함

    • JS 개발자들이 Faang 마케팅에 쉽게 넘어가서 인기가 없는 것 같음