カートに入れました

ReactのフレームワークRemixを使ってみる

メニュー

  • 簡単なブログサイトの構築
  • どうやってデータを取得するか
  • Remixのファイルルーティンをどうやって構築するか
  • テンプレートのナビゲーションメニューの修正
  • どうやってcssをインポートするか

テンプレート生成

npx create-remix@latest

名前は?

? Where would you like to create your app? remix-blog

テンプレートのタイプは?

? What type of app do you want to create?
❯ Just the basics

どこにデプロイする?

? Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployme
nt targets.
❯ Cloudflare Workers

TypeScriptかJavaScript?

? TypeScript or JavaScript?
❯ JavaScript
? Do you want me to run `npm install`? Y

これでcloudflareに簡単に上げることができるテンプレートが出来上がる

どうやってcssをインポートするか

appフォルダにstylesフォルダを作り、global.cssファイルを作る

それをroot.jsxにインポートすることでcssが反映されるようになる

app/root.jsx
import {
  Links,
  LiveReload,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "remix";

import globalStylesUrl from "~/styles/global.css";

export function meta() {
  return {
    charset: "utf-8",
    title: "New Remix App",
    viewport: "width=device-width,initial-scale=1",
  };
}

export function links() {
  return [
    { rel: "stylesheet", href: globalStylesUrl},
  ];
}

export default function App() {
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

テンプレートのナビゲーションメニューの修正

appフォルダにnavbar.jsxを作り

root.jsxにインポートし

bodyの中に含める

app/nabvar.jsx
import { Link, } from "remix";

export default function Navbar() {
  return (
    <header className="remix-app__header">
      <div className="container remix-app__header-content">
          <Link to="/" title="Remix" className="remix-app__header-home-link">
            <RemixLogo />
          </Link>
          <nav aria-label="Main navigation" className="remix-app__header-nav">
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/blog">Blog</Link>
              </li>

            </ul>
          </nav>
        </div>
    </header>
  );
}

function RemixLogo(props) {
  return (
    <svg
      viewBox="0 0 659 165"
      version="1.1"
      xmlns="http://www.w3.org/2000/svg"
      xmlnsXlink="http://www.w3.org/1999/xlink"
      aria-labelledby="remix-run-logo-title"
      role="img"
      width="106"
      height="30"
      fill="currentColor"
      {...props}
    >
      <title id="remix-run-logo-title">Remix Logo</title>
      <path d="M0 161V136H45.5416C53.1486 136 54.8003 141.638 54.8003 145V161H0Z M133.85 124.16C135.3 142.762 135.3 151.482 135.3 161H92.2283C92.2283 158.927 92.2653 157.03 92.3028 155.107C92.4195 149.128 92.5411 142.894 91.5717 130.304C90.2905 111.872 82.3473 107.776 67.7419 107.776H54.8021H0V74.24H69.7918C88.2407 74.24 97.4651 68.632 97.4651 53.784C97.4651 40.728 88.2407 32.816 69.7918 32.816H0V0H77.4788C119.245 0 140 19.712 140 51.2C140 74.752 125.395 90.112 105.665 92.672C122.32 96 132.057 105.472 133.85 124.16Z" />
      <path d="M654.54 47.1035H611.788L592.332 74.2395L573.388 47.1035H527.564L568.78 103.168L523.98 161.28H566.732L589.516 130.304L612.3 161.28H658.124L613.068 101.376L654.54 47.1035Z" />
    </svg>
  );
}
app/root.jsx

...

export default function App() {
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Navbar />
        <div className="remix-app__main" style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
          <div className="container remix-app__main-content">
            <Outlet />
          </div>
        </div>
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

Remixのファイルルーティンをどうやって構築するか

root.jsxのApp()の中にOutletコンポーネントが含まれている

この中がapp/routes以下のファイルに相当するようになる

<Link to={`/blog/posts/${post.id}`}>{post.title}</Link>

このリンク先がapp/routes/blog/posts/$PostId.jsxファイルを表示

どうやってデータを取得するか

loader関数の中のparams.PostIdで今のslugを取得している

app/routes/blog/posts/$PostId.jsx
import {Link, useLoaderData} from 'remix'
import blogStyles from "~/styles/blog.css";

export function links() {
  return [{ rel: "stylesheet", href: blogStyles }];
}

export let loader= ({params}) => {

  const post =  [
    {
        id: 1,
        title: "First post on Remix ",
        content:"Remix is a great framework...."
    },
    {
        id: 2,
        title: "Another post about Remix",
        content: "It has very good features...."
    },
    {
        id: 3,
        title: "Yet another post about remix",
        content: "It has very good features plus more...."
    }
  ].find((p)=> p.id === Number(params.PostId))

  if (!post) throw Error("No posts found")
  const data = {...post}
  return data


}


export default function GetPost() {
  const post= useLoaderData()
  return (
    <>
      <h2>{post.title}</h2>
      <p>{post.content}</p>
    </>
  )

}

データベースなどと連携している場合

loader関数内でデータを取得する

export let loader= ({params}) => {
  let res = fetch("https://api...")
  return res.json()
}

のようにすることができる

参考