Remix のチュートリアルをやってみた - Developers Blog 編
はじめに
Remix という Next.js や Gatsby 的な React ライブラリがいまノリにノッているらしい。 "Remix" なだけに
違いは何か、他と比べて何が優れているのか、は丁寧に紹介されている先輩方の記事を参照されたし
どんなかんじなのか、公式のチュートリアルを読みながら手を動かしてみた
思ったこと 3 つ
- データフェッチが Next.js よりスッキリ書けそう
- メタデータをページごとに定義できる柔軟性があるが、僕のような初心者では取りこぼしをしそうで怖い
- Nested Routes という Remix ならではの機能。使いこなせれば強力な味方になりそうだ
チュートリアルやってみて備忘録
これにチャレンジ
ルーティング
app/routes 以下のディレクトリ名やファイル名が URL のパス名に一致する
ダイナミックなルーティングは $filename.tsx という感じの名前にする ( 頭に $ をつける )
例
app/routes/index.tsx -> localhost:3000
app/routes/posts/index.tsx -> localhost:3000/posts
app/routes/posts/$slug.tsx -> localhost:3000/posts/your-slug-name
データローディング
loader() という関数内でデータフェッチをする
デフォルト関数内で useLoaderData() をすると loader() 内で return したデータを取れる
//...
export const loader = async () => {
return getPosts();
};
export default function Posts() {
const posts = useLoaderData<Post[]>();
//...
import 時のファイルパス
app/ 以下を ~/ で表している
app/post.ts -> ~/post
( 追記 ) これは tsconfig.json の設定だった。プロジェクトのデフォルトでそういうことにしたようだ
params の取り方
loader() を使う
app/route/posts/$slug.tsx の slug を取得したいときは
import type { LoaderFunction } from "remix";
export const loader: LoaderFunction = async ({ params }) => {
return params.slug;
}
export default function PostSlug() {
const slug = useLoaderData();
return (
<div>
<h1>{slug}</h1>
</div>
)
}
TypeScript で引数 params の型を特定するために loader に明示的に LoaderFunction 型を指定している
CSS を使う
Remix では各ページで <link> を埋め込むような形で CSS を使える。ページごとに別々の CSS を埋め込める反面、共通化するならそういうやり方を考えないといけなさそう
import adminStyles from "~/styles/admin.css"
export const links = () => {
return [{ rel: "stylesheet", href: adminStyles }]
}
// -> <link rel="stylesheet" href="...">
<link> 以外にもいろいろな meta タグをページごとに埋め込める
nested routes
Remix の特徴的な機能。ルートモジュール — Next.js でいうところのページコンポーネント — を入れ子にできる
データフェッチやエラーは各ルートモジュール内で完結していて、子のルートモジュールがエラーであってもその部分だけがエラーになり、親ルートモジュールはちゃんと表示される
app/routes/admin.tsx
app/routes/admin/index.tsx
app/routes/admin/new.tsx
こんな構成でファイルを作ったときに admin.tsx が親ルートモジュールとなり、 admin/ 以下の各ページは admin.tsx 側にポータルのようなもの ( Outlet ) を設置することで admin.tsx の中でコンポーネントのように表示ができる
import { Outlet, ... } from "remix"
//...
<nav>...</nav>
<main>
<Outlet />
</main>
// -> app/routes/admin/ 以下のページをパス名に応じて Outlet の場所に出すことができる

app/routes/admin/index.tsx を表示している

app/routes/admin/new.tsx を表示している
ヘッダー > サイドバー > ナビゲーションタブ
といった入れ子構造のページの場合に nested routes は有効。データフェッチやエラーハンドリングは一番親から降っていく必要はない
アクション
データのポストは remix の Form と action() 、 useActionData() を使う
HTML の form のように中で input や submit を組み立てる
submit した内容は action() で request として受けて中で DB に保存したり必要な処理をする
action() の中で条件によって error オブジェクトを返した場合、ページコンポーネントの中で
errors = useActionData()
とすればエラー時の処理を行える
まとめ
はじめてさわってみたのでまだメリデメを見いだせていない。たくさんの素晴らしい機能のほんの一部だけしか見えていない。継続して調査を進めようと思う
次回は Jokes App に挑戦したいと思う
Discussion