2.4K Views
July 18, 24
スライド概要
JTCのリアルトーク!KODANSHAt techとAEON
2024年07月18日(木)
Webフロントエンドエンジニア
【JTCのリアルトーク!KODANSHAtechとAEON】 RemixはポストRailsを 果たせるか? Github: junseinagao / Twitter: @junpai_code
自己紹介 長尾准誠 (ながおじゅんせい) Kodanshatech 合同会社 Webエンジニア 1997年2月生まれ (27歳) ・名古屋から来ました! ・Next.jsを使ったモダンフロントエンドの開発が得意です。 ・大学卒業後、フリーランスを2~3年間やったのち会社員になりました。 ・趣味はTesla買ったり、スノボ行ったり、スケボなどしてます。
Remixを簡単な業務管理アプリケーションを 作る観点から考えたい 規模としては小さいんだけど DBテーブル編集以上の管理画面を 専用に作って欲しいという要望・ 案件。世の中にたくさんある MVCはフレームワークは良い ソリューションだった
業務管理アプリケーションに求められるもの データ更新フローの開発の簡単さ ・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 %>
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)
});
SPAのフォーム作りは大変で時間がかかる ・フォームのstate管理の実装がそもそも難しい ◦ この手の一番人気な react-hook-form というライブラリはマイナーアップデート でも挙動の破壊的なちょくちょく入ることで有名 ◦ ≒ライブラリの内部ロジックが複雑 ・stateをリクエストするとき・したあとのバリデーション・エラー表示も大変 ・<form></form>とFormDataを使ってセマンティクスに実装しようとするとフォー ムの仕様に振り回される ◦ 同じname属性を持つinputが存在するとき配列 [] になり ◦ 単体の時はプリミティブ true な値になるなど ・SWRなどでリクエスト成功後の状態の再取得もハンドリングする
SPAではないWeb標準なフォームへの回帰 FormDataとサーバーのバリデーションに寄せる発想 ・Next.js API Routesを用いてSPAでもフォームをformとして扱う ・そしたら、Web標準な実装に近づきアプリケーションの複雑さも一定解消 される(?) API Routesが出てきた当初からこのように考える人たちはいた ・React Hook FormのAPI設計も<form>を強く意識しているし、next- runtimeのようなAPI RoutesでFormDataを扱ったりAPIを柔軟に実装 するためのヘルパーのようなライブラリもあった
実際にNext.jsでも<form>を活用する試みは... ツラかった。 ・FormDataをAPI Routesで受け付けてハンドリングするエコシステムがコ ミュニティで全く育ってなかった ・(全くのフレームワークなしにAPIサーバーを実装する感覚) FormDataをReactで扱うことには疑問が出る状況 ・「コミュニティに目立った知見もないし、使うとしてもサーバー側からの 通信としてcorsを避けながら別に建てたAPIサーバーへjsonのリクエスト 投げるぐらいが良いよね」という使われ方にとどまる
そこで Remix が登場した ・React Routerがルーティングとフォームを統合し ・Reactでフォームを扱う壁を乗り越えさせてくれる ・MVCのようにReactはUIとしてデータを表示することに 徹し、データは全てサーバー上で取得・サーバー上の ロジックで更新することを実現するAPIを揃える
有名な loader と action Loaders Component Action
有名な 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で返したオブジェクトを
簡単に取得できる
有名な 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管理は必要なくなる
Remixでなら MVCフレームワークのような FormDataを主体とした アプリケーションを実装できる
そんなRemixの魅力でも今日一番伝えたいのは <Form>とuseFetecherというAPIが素晴らしい ・以外と知らない・使っていない方もいると思う ・<Form>コンポーネントを使うと、ページ全体を更新すること なくSPA的にフォームPOSTを行える ・useFetcherフックスを使うと、URL遷移なしにフォームPOST を行える
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を使
ったリクエストに統一できる
まとめ ・RemixはフォームのWeb標準的な取り扱いをSPAと結合して昇華させた ・RemixはRailsのようなMVCフレームワークと近い開発体験で開発できる ・ポストRailsになれるかどうかは知らないが Prisma、conform、zod、 Remixの組み合わせはかなり良いし、価値提供に対してミニマムに高速に 開発できる
Remixを使った管理アプリケーション開発例 (おまけ) 自分は以下のスタックとRemixを組み合わせて何回か開発してる ・Prisma (ORM) ・conform + zod (サーバーに寄せたバリデーションと動的なフォーム操作) →JSエコシステムの強さでRemixの不足部分をカバーできる
ご清聴 ありがとうございました