木曜日, 10月 16, 2025
木曜日, 10月 16, 2025
- Advertisment -
ホームニューステックニュースRemix 3 を実際に動かしてみる

Remix 3 を実際に動かしてみる


Remix 3 は、React から脱却し、Web 標準に基づいた新しいフルスタック Web フレームワークとして再設計されました。Remix 3 は鋭意開発中ですが、この記事では React 代替に相当する箇所を部分的に動かして、実際に動作を検証してみます。

https://github.com/SoraKumo001/remix3-sample01

SPA アプリケーションとして動作させるための環境を用意します。今回はビルドに rolldown を使用します。

rolldown の設定

普通にビルドすれば依存パッケージのバンドルが行われるのですが、react/jsx-runtimeに関しては@remix-run/dom/jsx-runtimeに変換する設定が必要になります。

import { defineConfig } from "rolldown";

export default defineConfig({
  input: "src/index.tsx",
  output: {
    file: "public/bundle.js",
  },
  resolve: {
    alias: {
      "react/jsx-runtime": "@remix-run/dom/jsx-runtime",
      "react/jsx-dev-runtime": "@remix-run/dom/jsx-dev-runtime",
    },
  },
});

typescript の設定

Remix3 の jsx の形式を有効にするため、jsxImportSource@remix-run/domにする必要があります。

{
  "compilerOptions": {
    "strict": true,
    "lib": ["ES2024", "DOM", "DOM.Iterable"],
    "module": "ES2022",
    "moduleResolution": "Bundler",
    "target": "ESNext",
    "allowImportingTsExtensions": true,
    "rewriteRelativeImportExtensions": true,
    "verbatimModuleSyntax": true,
    "skipLibCheck": true,
    "jsx": "react-jsx",
    "jsxImportSource": "@remix-run/dom"
  }
}

カウントを回すだけ

まずはボタンを押して、カウントを表示するプログラムです。
これを見るとわかりますが、React との違いはステートが存在しないということです。React を初期から使っている人なら気がつくと思いますが、クラスコンポーネントのような動作を関数で行っています。再レンダリングの指示はthis.render()で能動的に呼び出します。
そして Remix3 ではイベントはすべてonに集約されており、そこでイベントを受け取ることになります。pressという、あらかじめ定義されているものを使っていますが、自分で定義することも可能です。

import { createRoot, type Remix } from "@remix-run/dom";
import { press } from "@remix-run/events/press";

function App(this: Remix.Handle) {
  let count = 0;
  return () => (
    button
      on={press(() => {
        count++;
        this.render();
      })}
    >
      Count: {count}
    button>
  );
}

createRoot(document.body).render(App />);

マウント、アンマウントの使い方

動作確認用に Test というコンポーネントを作って、ボタンを押したら消滅するようにします。
これを動かすと、マウント時にconnectが、アンマウント時にdisconnectが呼び出されます。
そして現時点で未実装なのか、ref が動作していません。

import { createRoot, type Remix } from "@remix-run/dom";
import { press } from "@remix-run/events/press";
import { connect, disconnect } from "@remix-run/dom";

function Test() {
  return (
    div
      ref={(n) => {
        console.log(n);
      }}
      on={[
        connect(() => {
          console.log("mount");
        }),
        disconnect(() => {
          console.log("unmount");
        }),
      ]}
    >
      Test
    div>
  );
}

function App(this: Remix.Handle) {
  let count = 0;
  return () => (
    >
      button
        on={press(() => {
          count++;
          this.render();
        })}
      >
        Count: {count}
      button>
      {count === 0 && Test />}
    >
  );
}

createRoot(document.body).render(App />);

その他のイベントの使い方

その他のイベントの使い方です。ここでの注意点ですが、Test コンポーネントは関数を戻しています。こうしないと、再レンダリングごとにmouseStateが初期化されてしまうので気をつけてください。

import { createRoot, type Remix } from "@remix-run/dom";
import { press } from "@remix-run/events/press";
import { dom } from "@remix-run/events";

function Test(this: Remix.Handle) {
  let mouseState = "mouseOut";
  return ({ value }: { value: string }) => (
    div
      on={[
        dom.mouseover(() => {
          mouseState = "mouseOver";
          this.render();
        }),
        dom.mouseout(() => {
          mouseState = "mouseOut";
          this.render();
        }),
      ]}
    >
      {value}:{mouseState}
    div>
  );
}

function App(this: Remix.Handle) {
  let count = 0;

  return () => (
    >
      button
        on={[
          press(() => {
            count++;
            this.render();
          }),
        ]}
      >
        Count: {count}
      button>
      Test value="test" />
    >
  );
}

createRoot(document.body).render(App />);

取り急ぎ、動くものを作って動作を確認してみました。興味のある人は是非いじってみてください。

https://zenn.dev/sora_kumo/articles/remix3-samples2



Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -