チュートリアルをやりながらRemixに入門する
ReactベースのフルスタックフレームワークのRemixを触ってみる。
ブログを作成する公式のチュートリアルを進めてみる。
--template
フラグを付けずによりミニマムに始めることもできるようだが、今回はチュートリアル通りにテンプレートを使用する。
npx create-remix@latest --template remix-run/indie-stack blog-tutorial
プロジェクト生成後 npm run dev
を実行。
http://localhost:3000 にアクセスして表示されれば、環境構築は無事成功。
ルーティングは app/routes/
の中に作成されたディレクトリやファイルが、そのままアプリケーションのURLとなるようだ。このあたりはNext.jsと同様。
以下のように app/routes/posts._index.tsx
を作成すると、 /posts
としてアクセスが可能。
export default function Posts() {
return (
<main>
<h1>Posts</h1>
</main>
);
}
データの読み込み
ブログ記事となるデータを読み込む。
Remixでは loader
という関数がサーバーのデータを読み込む際に使用される。
そして useLoaderData
関数を通して、コンポーネントへ繋がれる。
+ import { json } from "@remix-run/node";
+ import { useLoaderData } from "@remix-run/react";
+ export const loader = async () => {
+ return json({
+ posts: [
+ {
+ slug: "my-first-post",
+ title: "My First Post",
+ },
+ {
+ slug: "90s-mixtape",
+ title: "A Mixtape I Made Just For You",
+ },
+ ],
+ });
+ };
export default function Posts() {
+ const { posts } = useLoaderData<typeof loader>();
return (
<main>
<h1>Posts</h1>
</main>
);
}
データベースから取得する
今回使用したテンプレートではPostgreSQL + Prismaが使用されている。
-
schema.prisma
を定義 - マイグレーション
-
prisma/seed.ts
に投稿データを追加
上記3つの手順で、無事DBからの取得に切り替えられた。
ダイナミックルーティング
ブログ記事のような体裁は同じで内容だけ異なるページの動的な生成は app/routes/posts.$slug.tsx
という形式でファイルを作成することで実現できる。
Remixは以下のように相対パスが使えるとのこと。
わざわざ書かれているってことは他のフレームワークでは使えないことも多いのか?
<Link to="admin" className="text-red-600 underline">
Admin
</Link>
Reactの <Outlet />
を使えば共通部分はそのままに差異のある部分だけを変更可能。
import { json } from "@remix-run/node";
import {
Link,
Outlet,
useLoaderData,
} from "@remix-run/react";
import { getPosts } from "~/models/post.server";
export const loader = async () => {
return json({ posts: await getPosts() });
};
export default function PostAdmin() {
const { posts } = useLoaderData<typeof loader>();
return (
<div className="mx-auto max-w-4xl">
<h1 className="my-6 mb-2 border-b-2 text-center text-3xl">
Blog Admin
</h1>
<div className="grid grid-cols-4 gap-6">
<nav className="col-span-4 md:col-span-1">
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link
to={post.slug}
className="text-blue-600 underline"
>
{post.title}
</Link>
</li>
))}
</ul>
</nav>
<main className="col-span-4 md:col-span-3">
/* 以下が置き換わる */
<Outlet />
</main>
</div>
</div>
);
}
<Outlet />
はコードの共通化ができるだけでなく、共通部分は再レンダリングしないので、描画コストが抑えられるとのこと。
しかも特に設定は必要なく、親のパスがマッチしていると <Outlet />
内にレンダリングするようになるらしい。
チュートリアルでは
- 親
app/routes/posts.admin.tsx
- 子
app/routes/posts.admin.new.tsx
これで子の内容が <Outlet />
にレンダリングされる。
Web標準に逆らわない哲学
Remixの哲学にはWeb標準に逆らわず取り入れるという内容がある。
RemixはHTTPとHTMLの基礎の上で構築されている為、JavaScriptがなくても動かせる。実際にJavaScriptを切って試してみると面白い。だからと言ってJavaScriptが不要なわけではなく、ユーザー体験の向上のためにはJavaScriptが欠かせないということをRemixが言っていることを付け加えておく。
つまりRemixを上手く扱えればWeb標準が上手く扱えることに繋がり、フレームワークに囚われないスキルが身に付く。
以上で公式のチュートリアルをもとにRemixに触れてみた。
フロントとバックで言語が統一されている点や、Web標準に忠実な点はRemixの魅力だと思う。