Open4
Remixでブログを作る
以下を参考にRemixでブログをつくる。まとまったら記事にする。
- https://zenn.dev/shiro12/articles/353eb8711f5f32
- https://remix.run/docs/en/2.13.1/tutorials/blog#blog-tutoria
Node.jsのバージョン確認
% node --version
v18.17.0
npmのバージョン確認
% npm --version
9.8.1
creating-the-project
以下のコマンドを実行する
% npx create-remix@latest --template remix-run/indie-stack blog-tutorial
プロジェクトディレクトリに移動する
% cd blog-tutorial
手順に沿ってnpm run dev するとエラー
% npm run dev
> dev
> remix dev -c "npm run dev:serve"
💿 remix dev
info building...
info built (812ms)
> dev:serve
> NODE_OPTIONS="--import ./mocks/index.js" remix-serve ./build/index.js
node: --import is not allowed in NODE_OPTIONS
→最後の「node: --import is not allowed in NODE_OPTIONS
」を見る限り、importオプションがサポートされていないバージョンのNode.jsを使用しているようだった。
package.jsonの以下の部分をbefore→afterに変更する。
<!-- before -->
"dev": "remix dev -c \"npm run dev:serve\"",
<!-- after -->
"dev": "remix dev -c \"npm run dev:serve\"",
再度npm run devすると無事起動した。
npm run dev
> dev
> remix dev
💿 remix dev
info building...
info built (690ms)
[remix-serve] http://localhost:3000 (http://192.168.0.2:3000)
your-first-route
- app/routes/_index.tsxに以下を追記する。
「 Blog Posts」と書かれた「localhost:3000/posts」へのリンクが作成される。
まだアクセス先ページを作成していないので、「localhost:3000/posts」にアクセスすると、404エラーが発生する。
<div className="mx-auto mt-16 max-w-7xl text-center">
<Link
to="/posts"
className="text-xl text-blue-600 underline"
>
Blog Posts
</Link>
</div>
- app/routes/posts._index.tsx を作成し以下を記載する。
「localhost:3000/posts」にアクセスすると、「Posts」とだけ書かれたhtmlが表示されるようになる。
export default function Posts() {
return (
<main>
<h1>Posts</h1>
</main>
);
}
loading-data
Remixの仕組みは以下。
-
ルーティングの仕組み:
- ファイル構造がそのままURLパスになる
- app/routes/posts.tsx は /posts というURLに対応する
-
データの受け渡しの仕組み:
- 各ルートファイル(app/routes/ ディレクトリ内に配置されるファイルのこと)で loader() 関数を定義できる
- ユーザーがそのURLにアクセスすると、対応する loader() が実行される
- コンポーネント内で useLoaderData() を使うと、その loader() のデータを取得できる
- app/routes/posts._index.tsxを以下のように編集する
「localhost:3000/posts」にアクセスすると、loader()が実行されpostsというプロパティ名のjsonが返却される。useLoaderDataを使用することで、postsプロパティのjsonをコンポーネント内で使用できる。
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>
);
}
- app/routes/posts._index.tsxを以下のように編集する
「localhost:3000/posts」にアクセスすると、loader()が実行されpostsというプロパティ名のjsonが返却される。useLoaderDataを使用し、postsのjsonに対してmapを使って全要素に対して、titleの書かれたリンクを押下すると、slugに遷移するリンクを描画するJSXをjsonの要素数分生成できる。
import { json } from "@remix-run/node";
import { Link, 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>
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link
to={post.slug}
className="text-blue-600 underline"
>
{post.title}
</Link>
</li>
))}
</ul>
</main>
);
}