Open4

Remixでブログを作る

kohoshikohoshi

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)
kohoshikohoshi

your-first-route

  1. 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>
  1. app/routes/posts._index.tsx を作成し以下を記載する。
    「localhost:3000/posts」にアクセスすると、「Posts」とだけ書かれたhtmlが表示されるようになる。
export default function Posts() {
    return (
      <main>
        <h1>Posts</h1>
      </main>
    );
  }
kohoshikohoshi

loading-data

Remixの仕組みは以下。

  • ルーティングの仕組み:

    • ファイル構造がそのままURLパスになる
    • app/routes/posts.tsx は /posts というURLに対応する
  • データの受け渡しの仕組み:

    • 各ルートファイル(app/routes/ ディレクトリ内に配置されるファイルのこと)で loader() 関数を定義できる
    • ユーザーがそのURLにアクセスすると、対応する loader() が実行される
    • コンポーネント内で useLoaderData() を使うと、その loader() のデータを取得できる
  1. 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>
  );
}
  1. 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>
  );
}