RemixはポストRailsを果たせるか?

2.4K Views

July 18, 24

スライド概要

JTCのリアルトーク!KODANSHAt techとAEON
2024年07月18日(木)

profile-image

Webフロントエンドエンジニア

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

【JTCのリアルトーク!KODANSHAtechとAEON】 RemixはポストRailsを 果たせるか? Github: junseinagao / Twitter: @junpai_code

2.

自己紹介 長尾准誠 (ながおじゅんせい) Kodanshatech 合同会社 Webエンジニア 1997年2月生まれ (27歳) ・名古屋から来ました! ・Next.jsを使ったモダンフロントエンドの開発が得意です。 ・大学卒業後、フリーランスを2~3年間やったのち会社員になりました。 ・趣味はTesla買ったり、スノボ行ったり、スケボなどしてます。

3.

Remixを簡単な業務管理アプリケーションを 作る観点から考えたい 規模としては小さいんだけど DBテーブル編集以上の管理画面を 専用に作って欲しいという要望・ 案件。世の中にたくさんある MVCはフレームワークは良い ソリューションだった

4.

業務管理アプリケーションに求められるもの データ更新フローの開発の簡単さ ・HTMLフォームのハンドリング RailsやLaravelは form_with のような ヘルパー処理で解決 <% form_for @user do |form| %> <div class="field"> <%= form.label :name %> <%= form.text_field :name %> </div> <div class="field"> <%= form.label :email %> <%= form.text_field :email %> </div> <div class="actions"> <%= form.submit 'Save' %> </div> <% end %>

5.
[beta]
SPA (React) ではどうか?
inputなどフォームの要素をstate入力のUIとして使い
stateをFetch APIでajax通信するのが一般的
(フォームをリクエスト送信するためのformとしては使わず)
const response = await fetch('/api/form', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(formData)
});
6.

SPAのフォーム作りは大変で時間がかかる ・フォームのstate管理の実装がそもそも難しい ◦ この手の一番人気な react-hook-form というライブラリはマイナーアップデート でも挙動の破壊的なちょくちょく入ることで有名 ◦ ≒ライブラリの内部ロジックが複雑 ・stateをリクエストするとき・したあとのバリデーション・エラー表示も大変 ・<form></form>とFormDataを使ってセマンティクスに実装しようとするとフォー ムの仕様に振り回される ◦ 同じname属性を持つinputが存在するとき配列 [] になり ◦ 単体の時はプリミティブ true な値になるなど ・SWRなどでリクエスト成功後の状態の再取得もハンドリングする

7.

SPAではないWeb標準なフォームへの回帰 FormDataとサーバーのバリデーションに寄せる発想 ・Next.js API Routesを用いてSPAでもフォームをformとして扱う ・そしたら、Web標準な実装に近づきアプリケーションの複雑さも一定解消 される(?) API Routesが出てきた当初からこのように考える人たちはいた ・React Hook FormのAPI設計も<form>を強く意識しているし、next- runtimeのようなAPI RoutesでFormDataを扱ったりAPIを柔軟に実装 するためのヘルパーのようなライブラリもあった

8.

実際にNext.jsでも<form>を活用する試みは... ツラかった。 ・FormDataをAPI Routesで受け付けてハンドリングするエコシステムがコ ミュニティで全く育ってなかった ・(全くのフレームワークなしにAPIサーバーを実装する感覚) FormDataをReactで扱うことには疑問が出る状況 ・「コミュニティに目立った知見もないし、使うとしてもサーバー側からの 通信としてcorsを避けながら別に建てたAPIサーバーへjsonのリクエスト 投げるぐらいが良いよね」という使われ方にとどまる

9.

そこで Remix が登場した ・React Routerがルーティングとフォームを統合し ・Reactでフォームを扱う壁を乗り越えさせてくれる ・MVCのようにReactはUIとしてデータを表示することに 徹し、データは全てサーバー上で取得・サーバー上の ロジックで更新することを実現するAPIを揃える

10.

有名な loader と action Loaders Component Action

11.
[beta]
有名な loader と action
import type { LoaderFunctionArgs } from "@remix-run/node"; // or cloudflare/deno
import { json } from "@remix-run/node"; // or cloudflare/deno
import { useLoaderData, Form } from "@remix-run/react";

export async function loader({
  request,
}: LoaderFunctionArgs) {
  const user = await getUser(request);
  return json({
    displayName: user.displayName,
    email: user.email,
  });
}

export default function Component() {
  const user = useLoaderData<typeof loader>();
  return (
    <Form method="post" action="/account">
      <h1>Settings for {user.displayName}</h1>
    loaderで返したオブジェクトを
    簡単に取得できる
12.
[beta]
有名な loader と action
import type { ActionFunctionArgs } from "@remix-run/node"; // or cloudflare/deno
import { json } from "@remix-run/node"; // or cloudflare/deno
import { Form, useActionData } from "@remix-run/react";

export async function action({
  request,
}: ActionFunctionArgs) {
  const body = await request.formData();
  const name = body.get("visitorsName");
  return json({ message: `Hello, ${name}` });
}

export default function Invoices() {
  const data = useActionData<typeof action>();
  return (
    <Form method="post">
      <input type="text" name="visitorsName" />
      {data ? data.message : "Waiting..."}
    </Form>
  );
}
サーバー側のバリデーションの結果を簡単に
UIに返せる
<form>を使うことでname属性を付け
るだけでstate管理は必要なくなる
13.

Remixでなら MVCフレームワークのような FormDataを主体とした アプリケーションを実装できる

14.

そんなRemixの魅力でも今日一番伝えたいのは <Form>とuseFetecherというAPIが素晴らしい ・以外と知らない・使っていない方もいると思う ・<Form>コンポーネントを使うと、ページ全体を更新すること なくSPA的にフォームPOSTを行える ・useFetcherフックスを使うと、URL遷移なしにフォームPOST を行える

15.
[beta]
useFetcherの例
function SomeComponent() {
  const fetcher = useFetcher();
  return (
    <fetcher.Form method="post" action="/some/route">
      <input type="text" />
    </fetcher.Form>
  );
}
// const formData = new FormData()
// fetcher.submit(formData)
// という風にも使える
・form.submitをプログラマティカリに
操作できる
・「いいねボタン」のようなフォームの
形をしていないUIもフォームPOSTと
してデータ更新を実装できる
→アプリケーション全体でFormDataを使
ったリクエストに統一できる
16.

まとめ ・RemixはフォームのWeb標準的な取り扱いをSPAと結合して昇華させた ・RemixはRailsのようなMVCフレームワークと近い開発体験で開発できる ・ポストRailsになれるかどうかは知らないが Prisma、conform、zod、 Remixの組み合わせはかなり良いし、価値提供に対してミニマムに高速に 開発できる

17.

Remixを使った管理アプリケーション開発例 (おまけ) 自分は以下のスタックとRemixを組み合わせて何回か開発してる ・Prisma (ORM) ・conform + zod (サーバーに寄せたバリデーションと動的なフォーム操作) →JSエコシステムの強さでRemixの不足部分をカバーできる

18.

ご清聴 ありがとうございました