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